Skip to content

Commit

Permalink
Smoother video publish
Browse files Browse the repository at this point in the history
  • Loading branch information
hiroshihorie committed Sep 5, 2024
1 parent 7d2a6ae commit 7aa5b91
Show file tree
Hide file tree
Showing 7 changed files with 81 additions and 62 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,15 @@
"version" : "1.3.9"
}
},
{
"identity" : "client-components-swift",
"kind" : "remoteSourceControl",
"location" : "https://github.com/livekit/client-components-swift",
"state" : {
"revision" : "82fc74016db420393f425f54af12b5467f668e1f",
"version" : "0.0.1"
}
},
{
"identity" : "jwt-kit",
"kind" : "remoteSourceControl",
Expand Down
4 changes: 2 additions & 2 deletions LiveKitLivestreamExample.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -548,7 +548,7 @@
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO;
CODE_SIGN_ENTITLEMENTS = macOS/macOS.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 2024090501;
CURRENT_PROJECT_VERSION = 2024090502;
DEVELOPMENT_TEAM = 76TVFCUKK7;
ENABLE_HARDENED_RUNTIME = YES;
ENABLE_PREVIEWS = YES;
Expand Down Expand Up @@ -592,7 +592,7 @@
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO;
CODE_SIGN_ENTITLEMENTS = macOS/macOS.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 2024090501;
CURRENT_PROJECT_VERSION = 2024090502;
DEVELOPMENT_TEAM = 76TVFCUKK7;
ENABLE_HARDENED_RUNTIME = YES;
ENABLE_PREVIEWS = YES;
Expand Down
92 changes: 48 additions & 44 deletions Shared/Contexts/RoomContext.swift
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ final class RoomContext: NSObject, ObservableObject {
@Published public var enableChat: Bool = true
@Published public var viewersCanRequestToJoin: Bool = true

public let localCameraTrack = LocalVideoTrack.createCameraTrack()
public var localCameraTrackPublication: LocalTrackPublication?

// Computed helpers
public var isStreamOwner: Bool {
room.typedMetadata.creatorIdentity == room.localParticipant.identity?.stringValue
Expand All @@ -79,19 +82,14 @@ final class RoomContext: NSObject, ObservableObject {
logger.info("RoomContext created")
}

public func set(step: Step) {
@MainActor
public func set(step: Step) async {
self.step = step
}

public func backToWelcome() {
Task { @MainActor in
self.step = .welcome
}
}

public func backToPrepare() {
Task { @MainActor in
self.step = .streamerPrepare
if step == .streamerPrepare {
try? await localCameraTrack.start()
} else if step == .welcome {
try? await localCameraTrack.stop()
}
}

Expand Down Expand Up @@ -119,19 +117,12 @@ final class RoomContext: NSObject, ObservableObject {
logger.debug("Connecting to room... \(res.connectionDetails)")

try await room.connect(url: res.connectionDetails.wsURL, token: res.connectionDetails.token)
Task { @MainActor in
self.step = .stream

// Separate attempt to publish
Task {
do {
try await room.localParticipant.setCamera(enabled: true)
try await room.localParticipant.setMicrophone(enabled: true)
} catch {
logger.error("Failed to publish, error: \(error)")
}
}
}

await set(step: .stream)

localCameraTrackPublication = try await room.localParticipant.publish(videoTrack: localCameraTrack)
try await room.localParticipant.setMicrophone(enabled: true)

logger.info("Connected")
} catch let publishError {
await room.disconnect()
Expand All @@ -155,9 +146,7 @@ final class RoomContext: NSObject, ObservableObject {
logger.debug("Connecting to room... \(res.connectionDetails)")

try await room.connect(url: res.connectionDetails.wsURL, token: res.connectionDetails.token)
Task { @MainActor in
self.step = .stream
}
await set(step: .stream)
logger.info("Connected")
} catch {
await room.disconnect()
Expand Down Expand Up @@ -287,8 +276,8 @@ extension RoomContext: RoomDelegate {
if case .disconnected = connectionState,
case .connected = oldValue
{
Task { @MainActor in
self.step = .welcome
Task {
await set(step: .welcome)
}

logger.debug("Did disconnect")
Expand All @@ -305,22 +294,37 @@ extension RoomContext: RoomDelegate {
}

func room(_: Room, participant: Participant, didUpdatePermissions _: ParticipantPermissions) {
if let participant = participant as? LocalParticipant,
participant.canPublish
{
// Separate attempt to publish
Task {
do {
// Ensure permissions...
guard await LiveKitSDK.ensureDeviceAccess(for: [.video, .audio]) else {
// Both .video and .audio device permissions are required...
throw LivestreamError.permissions
}
if let participant = participant as? LocalParticipant {
if participant.canPublish {
// Separate attempt to publish
Task {
do {
// Ensure permissions...
guard await LiveKitSDK.ensureDeviceAccess(for: [.video, .audio]) else {
// Both .video and .audio device permissions are required...
throw LivestreamError.permissions
}

try await participant.setCamera(enabled: true)
try await participant.setMicrophone(enabled: true)
} catch {
logger.error("Failed to publish, error: \(error)")
if localCameraTrackPublication == nil {
localCameraTrackPublication = try await participant.publish(videoTrack: localCameraTrack)
}

try await participant.setMicrophone(enabled: true)
} catch {
logger.error("Failed to publish, error: \(error)")
}
}
} else {
Task {
do {
if let localCameraTrackPublication {
try await participant.unpublish(publication: localCameraTrackPublication)
self.localCameraTrackPublication = nil
}
try await participant.setMicrophone(enabled: false)
} catch {
logger.error("Failed to unpublish, error: \(error)")
}
}
}
}
Expand Down
4 changes: 3 additions & 1 deletion Shared/StreamerPrepareView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,9 @@ struct StreamerPrepareView: View {
}

StyledButton {
roomCtx.backToWelcome()
Task {
await roomCtx.set(step: .welcome)
}
} label: {
Text("Back")
}
Expand Down
4 changes: 3 additions & 1 deletion Shared/ViewerPrepareView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,9 @@ struct ViewerPrepareView: View {
}

StyledButton(isEnabled: !roomCtx.connectBusy) {
roomCtx.backToWelcome()
Task {
await roomCtx.set(step: .welcome)
}
} label: {
Text("Back")
}
Expand Down
22 changes: 10 additions & 12 deletions Shared/Views/PublisherVideoView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,21 +31,19 @@ extension Image {
}

struct PublisherVideoPreview: View {
var body: some View {
ZStack(alignment: .topLeading) {
LocalCameraPreview()
.frame(maxWidth: .infinity, maxHeight: .infinity)
.cornerRadius(6)
}
}
}
@EnvironmentObject var roomCtx: RoomContext
@Environment(\.liveKitUIOptions) var ui: UIOptions

struct PublisherVideoView: View {
var body: some View {
ZStack(alignment: .topLeading) {
LocalCameraVideoView()
.frame(maxWidth: .infinity, maxHeight: .infinity)
.cornerRadius(6)
GeometryReader { geometry in
ZStack {
ui.videoDisabledView(geometry: geometry)
SwiftUIVideoView(roomCtx.localCameraTrack, mirrorMode: .mirror)
}
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
.cornerRadius(6)
}
}
}
Expand Down
8 changes: 6 additions & 2 deletions Shared/WelcomeView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,17 @@ struct WelcomeView: View {
Spacer()

StyledButton(style: .primary) {
roomCtx.set(step: .streamerPrepare)
Task {
await roomCtx.set(step: .streamerPrepare)
}
} label: {
Text("Start a livestream")
}

StyledButton {
roomCtx.set(step: .viewerPrepare)
Task {
await roomCtx.set(step: .viewerPrepare)
}
} label: {
Text("Join a livestream")
}
Expand Down

0 comments on commit 7aa5b91

Please sign in to comment.