Skip to content

Commit

Permalink
Add PiP support
Browse files Browse the repository at this point in the history
  • Loading branch information
aravind-raveendran committed Jan 8, 2024
1 parent 341ba2a commit 13b34ca
Show file tree
Hide file tree
Showing 13 changed files with 382 additions and 130 deletions.
25 changes: 17 additions & 8 deletions Sources/DolbyIORTSCore/Model/StreamSourceViewRenderer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,29 @@ public class StreamSourceViewRenderer: Identifiable {
static let defaultVideoTileSize = CGSize(width: 533, height: 300)
}

private let renderer: MCIosVideoRenderer

let videoTrack: MCVideoTrack

public let streamSource: StreamSource
public let videoTrack: MCVideoTrack
public let playbackView: MCSampleBufferVideoUIView
public let pipView: MCSampleBufferVideoUIView
public let id = UUID()

private let renderer: MCIosVideoRenderer

public init(_ streamSource: StreamSource) {
self.streamSource = streamSource
let videoTrack = streamSource.videoTrack.track
self.renderer = MCIosVideoRenderer()
self.videoTrack = videoTrack

let playbackView = MCSampleBufferVideoUIView()
playbackView.scalingMode = .aspectFit
playbackView.attach(videoTrack: videoTrack, mirrored: false)
self.playbackView = playbackView

let pipView = MCSampleBufferVideoUIView()
pipView.scalingMode = .aspectFit
pipView.attach(videoTrack: videoTrack, mirrored: false)
self.pipView = pipView

Task {
await MainActor.run {
Expand All @@ -37,10 +50,6 @@ public class StreamSourceViewRenderer: Identifiable {
public var frameHeight: CGFloat {
hasValidDimensions ? CGFloat(renderer.getHeight()) : Constants.defaultVideoTileSize.height
}

public var playbackView: UIView {
renderer.getView()
}
}

// MARK: Helper functions
Expand Down
70 changes: 70 additions & 0 deletions Sources/DolbyIORTSUIKit/Private/Managers/PiPManager.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
//
// PiPManager.swift
//

import AVFoundation
import AVKit
import Foundation
import MillicastSDK
import UIKit

final class PiPManager: NSObject {
static let shared: PiPManager = PiPManager()

private override init() {}

private(set) var pipController: AVPictureInPictureController?
private(set) var pipView: MCSampleBufferVideoUIView?

func set(pipView: MCSampleBufferVideoUIView, with targetView: UIView) {
pipController?.stopPictureInPicture()

guard AVPictureInPictureController.isPictureInPictureSupported() else {
return
}

let pipVideoCallViewController = AVPictureInPictureVideoCallViewController()
pipVideoCallViewController.view.addSubview(pipView)
pipView.translatesAutoresizingMaskIntoConstraints = false

NSLayoutConstraint.activate([
pipVideoCallViewController.view.topAnchor.constraint(equalTo: pipView.topAnchor),
pipVideoCallViewController.view.leadingAnchor.constraint(equalTo: pipView.leadingAnchor),
pipView.bottomAnchor.constraint(equalTo: pipVideoCallViewController.view.bottomAnchor),
pipView.trailingAnchor.constraint(equalTo: pipVideoCallViewController.view.trailingAnchor)
])
pipVideoCallViewController.preferredContentSize = targetView.frame.size

let pipContentSource = AVPictureInPictureController.ContentSource(
activeVideoCallSourceView: targetView,
contentViewController: pipVideoCallViewController
)

let pipController = AVPictureInPictureController(contentSource: pipContentSource)
pipController.canStartPictureInPictureAutomaticallyFromInline = true
pipController.delegate = self

NotificationCenter.default
.addObserver(forName: UIApplication.didBecomeActiveNotification, object: nil, queue: .main) { [weak self] _ in
self?.stopPiP()
}

self.pipView = pipView
self.pipController = pipController
}

func stopPiP() {
pipController?.stopPictureInPicture()
}
}

extension PiPManager: AVPictureInPictureControllerDelegate {
func pictureInPictureControllerDidStartPictureInPicture(_ pictureInPictureController: AVPictureInPictureController) {
}

func pictureInPictureControllerDidStopPictureInPicture(_ pictureInPictureController: AVPictureInPictureController) {
}

func pictureInPictureController(_ pictureInPictureController: AVPictureInPictureController, failedToStartPictureInPictureWithError error: Error) {
}
}
Loading

0 comments on commit 13b34ca

Please sign in to comment.