Skip to content

Commit

Permalink
Re-implementation of passthrough.
Browse files Browse the repository at this point in the history
  • Loading branch information
shogo4405 committed Sep 14, 2024
1 parent 01275f7 commit 44e1bb9
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 19 deletions.
31 changes: 24 additions & 7 deletions Examples/iOS/Screencast/SampleHandler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,18 @@ nonisolated let logger = LBLogger.with(kHaishinKitIdentifier)
@available(iOS 10.0, *)
final class SampleHandler: RPBroadcastSampleHandler, @unchecked Sendable {
private var slider: UISlider?

private var _rotator: Any?
@available(iOS 16.0, tvOS 16.0, macOS 13.0, *)
private var rotator: VideoRotator? {
get { _rotator as? VideoRotator }
set { _rotator = newValue }
get {
_rotator as? VideoRotator
}
set {
_rotator = newValue
}
}

private var isVideoRotationEnabled = false {
didSet {
if isVideoRotationEnabled, #available(iOS 16.0, tvOS 16.0, macOS 13.0, *) {
Expand All @@ -41,10 +47,16 @@ final class SampleHandler: RPBroadcastSampleHandler, @unchecked Sendable {
*/
LBLogger.with(kHaishinKitIdentifier).level = .info
// mixer.audioMixerSettings.tracks[1] = .default
isVideoRotationEnabled = true
isVideoRotationEnabled = false
Task {
await mixer.setMultiTrackAudioMixingEnabled(true)
await netStreamSwitcher.setPreference(Preference.default)
// ReplayKit is sensitive to memory, so we limit the queue to a maximum of five items.
if let stream = await netStreamSwitcher.stream {
var videoSetting = await mixer.videoMixerSettings
videoSetting.mode = .passthrough
await stream.setVideoInputBufferCounts(5)
await mixer.setVideoMixerSettings(videoSetting)
await mixer.addOutput(stream)
}
await netStreamSwitcher.open(.ingest)
Expand Down Expand Up @@ -86,14 +98,19 @@ final class SampleHandler: RPBroadcastSampleHandler, @unchecked Sendable {
Task { await mixer.append(sampleBuffer) }
}
case .audioMic:
if CMSampleBufferDataIsReady(sampleBuffer) {
if sampleBuffer.dataReadiness == .ready {
Task { await mixer.append(sampleBuffer, track: 0) }
}
case .audioApp:
if let volume = slider?.value {
// mixer.audioMixerSettings.tracks[1]?.volume = volume * 0.5
Task { @MainActor in
if let volume = slider?.value {
var audioMixerSettings = await mixer.audioMixerSettings
audioMixerSettings.tracks[1] = .default
audioMixerSettings.tracks[1]?.volume = volume * 0.5
await mixer.setAudioMixerSettings(audioMixerSettings)
}
}
if CMSampleBufferDataIsReady(sampleBuffer) {
if sampleBuffer.dataReadiness == .ready {
Task { await mixer.append(sampleBuffer, track: 1) }
}
@unknown default:
Expand Down
39 changes: 27 additions & 12 deletions Sources/Mixer/MediaMixer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,10 @@ public final actor MediaMixer {

/// Sets the video mixier settings.
public func setVideoMixerSettings(_ settings: VideoMixerSettings) {
let mode = self.videoMixerSettings.mode
if mode != settings.mode {
setVideoRenderingMode(settings.mode)
}
videoIO.mixerSettings = settings
Task { @ScreenActor in
screen.videoTrackScreenObject.track = settings.mainTrack
Expand Down Expand Up @@ -287,6 +291,28 @@ public final actor MediaMixer {
}
}

func setVideoRenderingMode(_ mode: VideoMixerSettings.Mode) {
switch mode {
case .passthrough:
Task { @ScreenActor in
displayLink.stopRunning()
}
case .offscreen:
Task { @ScreenActor in
displayLink.preferredFramesPerSecond = await Int(frameRate)
displayLink.startRunning()
for await _ in displayLink.updateFrames where displayLink.isRunning {
guard let buffer = screen.makeSampleBuffer() else {
continue
}
for output in await self.outputs where await output.videoTrackId == UInt8.max {
output.mixer(self, didOutput: buffer)
}
}
}
}
}

#if os(iOS) || os(tvOS) || os(visionOS)
func setBackgroundMode(_ background: Bool) {
guard #available(tvOS 17.0, *) else {
Expand Down Expand Up @@ -333,18 +359,7 @@ extension MediaMixer: AsyncRunner {
}
}
}
Task { @ScreenActor in
displayLink.preferredFramesPerSecond = await Int(frameRate)
displayLink.startRunning()
for await _ in displayLink.updateFrames where await isRunning {
guard let buffer = screen.makeSampleBuffer() else {
continue
}
for output in await self.outputs where await output.videoTrackId == UInt8.max {
output.mixer(self, didOutput: buffer)
}
}
}
setVideoRenderingMode(videoMixerSettings.mode)
#if os(iOS) || os(tvOS) || os(visionOS)
NotificationCenter
.Publisher(center: .default, name: UIApplication.didEnterBackgroundNotification, object: nil)
Expand Down

0 comments on commit 44e1bb9

Please sign in to comment.