diff --git a/iOS/APIExample-SwiftUI/APIExample-SwiftUI.xcodeproj/project.pbxproj b/iOS/APIExample-SwiftUI/APIExample-SwiftUI.xcodeproj/project.pbxproj index f0bdcf9e6..4f59cbda8 100644 --- a/iOS/APIExample-SwiftUI/APIExample-SwiftUI.xcodeproj/project.pbxproj +++ b/iOS/APIExample-SwiftUI/APIExample-SwiftUI.xcodeproj/project.pbxproj @@ -92,14 +92,11 @@ 4C9309C22CBA91530085EFF9 /* JoinMultiChannel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C9309722CBA91520085EFF9 /* JoinMultiChannel.swift */; }; 4C9309C32CBA91530085EFF9 /* JoinMultiChannelRTC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C9309732CBA91520085EFF9 /* JoinMultiChannelRTC.swift */; }; 4C9309C42CBA91530085EFF9 /* PictureInPicture.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C9309752CBA91530085EFF9 /* PictureInPicture.swift */; }; - 4C9309C52CBA91530085EFF9 /* SDKRenderRTC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C9309772CBA91530085EFF9 /* SDKRenderRTC.swift */; }; - 4C9309C62CBA91530085EFF9 /* SDKRenderViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C9309782CBA91530085EFF9 /* SDKRenderViewModel.swift */; }; - 4C9309C72CBA91530085EFF9 /* SDKRenderExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C9309792CBA91530085EFF9 /* SDKRenderExample.swift */; }; 4C9309C82CBA91530085EFF9 /* PIPDisplayView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C93097B2CBA91530085EFF9 /* PIPDisplayView.swift */; }; 4C9309C92CBA91530085EFF9 /* PixelBufferRenderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C93097C2CBA91530085EFF9 /* PixelBufferRenderView.swift */; }; - 4C9309CA2CBA91530085EFF9 /* CustomRenderViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C93097E2CBA91530085EFF9 /* CustomRenderViewModel.swift */; }; - 4C9309CB2CBA91530085EFF9 /* CustomRenderRTC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C93097F2CBA91530085EFF9 /* CustomRenderRTC.swift */; }; - 4C9309CC2CBA91530085EFF9 /* CustomRenderExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C9309802CBA91530085EFF9 /* CustomRenderExample.swift */; }; + 4C9309CA2CBA91530085EFF9 /* PixelBufferRenderViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C93097E2CBA91530085EFF9 /* PixelBufferRenderViewModel.swift */; }; + 4C9309CB2CBA91530085EFF9 /* PixelBufferRenderRTC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C93097F2CBA91530085EFF9 /* PixelBufferRenderRTC.swift */; }; + 4C9309CC2CBA91530085EFF9 /* PixelBufferRenderExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C9309802CBA91530085EFF9 /* PixelBufferRenderExample.swift */; }; 4C9309CD2CBA91530085EFF9 /* VideoMetadata.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C9309822CBA91530085EFF9 /* VideoMetadata.swift */; }; 4C9309CE2CBA91530085EFF9 /* VideoMetaDataRTC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C9309832CBA91530085EFF9 /* VideoMetaDataRTC.swift */; }; 4C9309CF2CBA91530085EFF9 /* RTMPStreamRTC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C9309852CBA91530085EFF9 /* RTMPStreamRTC.swift */; }; @@ -269,14 +266,11 @@ 4C9309722CBA91520085EFF9 /* JoinMultiChannel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JoinMultiChannel.swift; sourceTree = ""; }; 4C9309732CBA91520085EFF9 /* JoinMultiChannelRTC.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JoinMultiChannelRTC.swift; sourceTree = ""; }; 4C9309752CBA91530085EFF9 /* PictureInPicture.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PictureInPicture.swift; sourceTree = ""; }; - 4C9309772CBA91530085EFF9 /* SDKRenderRTC.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SDKRenderRTC.swift; sourceTree = ""; }; - 4C9309782CBA91530085EFF9 /* SDKRenderViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SDKRenderViewModel.swift; sourceTree = ""; }; - 4C9309792CBA91530085EFF9 /* SDKRenderExample.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SDKRenderExample.swift; sourceTree = ""; }; 4C93097B2CBA91530085EFF9 /* PIPDisplayView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PIPDisplayView.swift; sourceTree = ""; }; 4C93097C2CBA91530085EFF9 /* PixelBufferRenderView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PixelBufferRenderView.swift; sourceTree = ""; }; - 4C93097E2CBA91530085EFF9 /* CustomRenderViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CustomRenderViewModel.swift; sourceTree = ""; }; - 4C93097F2CBA91530085EFF9 /* CustomRenderRTC.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CustomRenderRTC.swift; sourceTree = ""; }; - 4C9309802CBA91530085EFF9 /* CustomRenderExample.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CustomRenderExample.swift; sourceTree = ""; }; + 4C93097E2CBA91530085EFF9 /* PixelBufferRenderViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PixelBufferRenderViewModel.swift; sourceTree = ""; }; + 4C93097F2CBA91530085EFF9 /* PixelBufferRenderRTC.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PixelBufferRenderRTC.swift; sourceTree = ""; }; + 4C9309802CBA91530085EFF9 /* PixelBufferRenderExample.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PixelBufferRenderExample.swift; sourceTree = ""; }; 4C9309822CBA91530085EFF9 /* VideoMetadata.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VideoMetadata.swift; sourceTree = ""; }; 4C9309832CBA91530085EFF9 /* VideoMetaDataRTC.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VideoMetaDataRTC.swift; sourceTree = ""; }; 4C9309852CBA91530085EFF9 /* RTMPStreamRTC.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RTMPStreamRTC.swift; sourceTree = ""; }; @@ -760,23 +754,12 @@ isa = PBXGroup; children = ( 4C9309752CBA91530085EFF9 /* PictureInPicture.swift */, - 4C9309762CBA91530085EFF9 /* SDKRender */, 4C93097A2CBA91530085EFF9 /* PIPCommon */, 4C93097D2CBA91530085EFF9 /* CustomRender */, ); path = PictureInPicture; sourceTree = ""; }; - 4C9309762CBA91530085EFF9 /* SDKRender */ = { - isa = PBXGroup; - children = ( - 4C9309772CBA91530085EFF9 /* SDKRenderRTC.swift */, - 4C9309782CBA91530085EFF9 /* SDKRenderViewModel.swift */, - 4C9309792CBA91530085EFF9 /* SDKRenderExample.swift */, - ); - path = SDKRender; - sourceTree = ""; - }; 4C93097A2CBA91530085EFF9 /* PIPCommon */ = { isa = PBXGroup; children = ( @@ -789,9 +772,9 @@ 4C93097D2CBA91530085EFF9 /* CustomRender */ = { isa = PBXGroup; children = ( - 4C93097E2CBA91530085EFF9 /* CustomRenderViewModel.swift */, - 4C93097F2CBA91530085EFF9 /* CustomRenderRTC.swift */, - 4C9309802CBA91530085EFF9 /* CustomRenderExample.swift */, + 4C93097E2CBA91530085EFF9 /* PixelBufferRenderViewModel.swift */, + 4C93097F2CBA91530085EFF9 /* PixelBufferRenderRTC.swift */, + 4C9309802CBA91530085EFF9 /* PixelBufferRenderExample.swift */, ); path = CustomRender; sourceTree = ""; @@ -1100,7 +1083,7 @@ buildActionMask = 2147483647; files = ( 4C93076A2CB961150085EFF9 /* CircularBuffer.c in Sources */, - 4C9309CA2CBA91530085EFF9 /* CustomRenderViewModel.swift in Sources */, + 4C9309CA2CBA91530085EFF9 /* PixelBufferRenderViewModel.swift in Sources */, 4C9309D52CBA91530085EFF9 /* AudioWaveformRTC.swift in Sources */, 4C9309CE2CBA91530085EFF9 /* VideoMetaDataRTC.swift in Sources */, 4C9309C12CBA91530085EFF9 /* CustomPCMAudioSource.swift in Sources */, @@ -1113,7 +1096,7 @@ 4C93077A2CB961150085EFF9 /* VideoUIView.swift in Sources */, 4C9309B92CBA91530085EFF9 /* LiveStreaming.swift in Sources */, 4C9307FC2CBA6F790085EFF9 /* JoinChannelAudio.swift in Sources */, - 4C9309CB2CBA91530085EFF9 /* CustomRenderRTC.swift in Sources */, + 4C9309CB2CBA91530085EFF9 /* PixelBufferRenderRTC.swift in Sources */, 4C9309D12CBA91530085EFF9 /* CustomAudioRender.swift in Sources */, 4C93076E2CB961150085EFF9 /* KFMP4Demuxer.m in Sources */, 4C9309C22CBA91530085EFF9 /* JoinMultiChannel.swift in Sources */, @@ -1122,7 +1105,7 @@ 4C9309C92CBA91530085EFF9 /* PixelBufferRenderView.swift in Sources */, 4C93075D2CB961150085EFF9 /* AgoraCustomEncryption.mm in Sources */, 4C9307652CB961150085EFF9 /* AgoraCameraSourcePush.swift in Sources */, - 4C9309CC2CBA91530085EFF9 /* CustomRenderExample.swift in Sources */, + 4C9309CC2CBA91530085EFF9 /* PixelBufferRenderExample.swift in Sources */, 4C9308012CBA6F8D0085EFF9 /* JoinChannelVideoRTC.swift in Sources */, 4C9309DC2CBA91530085EFF9 /* VoiceChanger.swift in Sources */, 4C93076F2CB961150085EFF9 /* MediaUtils.m in Sources */, @@ -1139,7 +1122,6 @@ 4C9309ED2CBA95530085EFF9 /* SpatialAudioRTC.swift in Sources */, 4C9309DA2CBA91530085EFF9 /* RhythmPlayerRTC.swift in Sources */, 4C9309BB2CBA91530085EFF9 /* CreateDataStream.swift in Sources */, - 4C9309C62CBA91530085EFF9 /* SDKRenderViewModel.swift in Sources */, 4C9309B62CBA91530085EFF9 /* MutliCameraRTC.swift in Sources */, 4C93077D2CB961150085EFF9 /* KeyCenter.swift in Sources */, 4C9307692CB961150085EFF9 /* AgoraMetalShader.metal in Sources */, @@ -1154,7 +1136,6 @@ 4C9307612CB961150085EFF9 /* NetworkManager.swift in Sources */, 4C9307C52CB961160085EFF9 /* APIExample_SwiftUIApp.swift in Sources */, 4C9309DB2CBA91530085EFF9 /* VoiceChangerRTC.swift in Sources */, - 4C9309C72CBA91530085EFF9 /* SDKRenderExample.swift in Sources */, F73B018D2CC10E240077B7D2 /* ViewExtensions.swift in Sources */, 4C9309AB2CBA91530085EFF9 /* RawAudioDataRTC.swift in Sources */, 4C9307752CB961150085EFF9 /* AgoraPcmSourcePush.swift in Sources */, @@ -1174,7 +1155,6 @@ 4C93075E2CB961150085EFF9 /* SettingsView.swift in Sources */, 4C93080C2CBA712F0085EFF9 /* JoinChannelVideoToken.swift in Sources */, 4C9309BA2CBA91530085EFF9 /* LiveStreamingRTC.swift in Sources */, - 4C9309C52CBA91530085EFF9 /* SDKRenderRTC.swift in Sources */, 4C9309E42CBA91530085EFF9 /* ContentInspect.swift in Sources */, 4C9309D92CBA91530085EFF9 /* RhythmPlayer.swift in Sources */, 4C9307622CB961150085EFF9 /* JSONObject.swift in Sources */, diff --git a/iOS/APIExample-SwiftUI/APIExample-SwiftUI/Examples/Advanced/PictureInPicture/CustomRender/CustomRenderExample.swift b/iOS/APIExample-SwiftUI/APIExample-SwiftUI/Examples/Advanced/PictureInPicture/CustomRender/PixelBufferRenderExample.swift similarity index 81% rename from iOS/APIExample-SwiftUI/APIExample-SwiftUI/Examples/Advanced/PictureInPicture/CustomRender/CustomRenderExample.swift rename to iOS/APIExample-SwiftUI/APIExample-SwiftUI/Examples/Advanced/PictureInPicture/CustomRender/PixelBufferRenderExample.swift index 1663b9b0d..95b4370e9 100644 --- a/iOS/APIExample-SwiftUI/APIExample-SwiftUI/Examples/Advanced/PictureInPicture/CustomRender/CustomRenderExample.swift +++ b/iOS/APIExample-SwiftUI/APIExample-SwiftUI/Examples/Advanced/PictureInPicture/CustomRender/PixelBufferRenderExample.swift @@ -7,8 +7,8 @@ import SwiftUI -struct CustomRenderMockContainerView: View { - @ObservedObject var viewModel: CustomRenderViewModel +struct PixelBufferRenderMockContainerView: View { + @ObservedObject var viewModel: PixelBufferRenderViewModel var localView = PixelBufferCustomRenderView() @@ -23,24 +23,24 @@ struct CustomRenderMockContainerView: View { } @available(iOS 15.0, *) -struct CustomRenderExample: View { +struct PixelBufferRenderExample: View { @State var configs: [String: Any] //mock data - @StateObject private var customRenderViewModel: CustomRenderViewModel + @StateObject private var customRenderViewModel: PixelBufferRenderViewModel //pip controller @StateObject private var pipViewModel: PIPViewModel - let myContainerView: CustomRenderMockContainerView + let myContainerView: PixelBufferRenderMockContainerView init(configs: [String: Any]) { _configs = State(initialValue: configs) - let viewModel = CustomRenderViewModel(configs: configs) + let viewModel = PixelBufferRenderViewModel(configs: configs) _customRenderViewModel = StateObject(wrappedValue: viewModel) - myContainerView = CustomRenderMockContainerView(viewModel: viewModel) + myContainerView = PixelBufferRenderMockContainerView(viewModel: viewModel) let pipSourceView = UIHostingController(rootView: myContainerView).view! _pipViewModel = StateObject(wrappedValue: PIPViewModel(pipSourceView: pipSourceView)) } @@ -84,7 +84,7 @@ struct CustomRenderExample: View { struct CustomRenderExamplePreviews: PreviewProvider { static var previews: some View { if #available(iOS 15.0, *) { - CustomRenderExample(configs: [:]) + PixelBufferRenderExample(configs: [:]) } else { // Fallback on earlier versions } diff --git a/iOS/APIExample-SwiftUI/APIExample-SwiftUI/Examples/Advanced/PictureInPicture/CustomRender/CustomRenderRTC.swift b/iOS/APIExample-SwiftUI/APIExample-SwiftUI/Examples/Advanced/PictureInPicture/CustomRender/PixelBufferRenderRTC.swift similarity index 95% rename from iOS/APIExample-SwiftUI/APIExample-SwiftUI/Examples/Advanced/PictureInPicture/CustomRender/CustomRenderRTC.swift rename to iOS/APIExample-SwiftUI/APIExample-SwiftUI/Examples/Advanced/PictureInPicture/CustomRender/PixelBufferRenderRTC.swift index 9f857738c..cad87ed20 100644 --- a/iOS/APIExample-SwiftUI/APIExample-SwiftUI/Examples/Advanced/PictureInPicture/CustomRender/CustomRenderRTC.swift +++ b/iOS/APIExample-SwiftUI/APIExample-SwiftUI/Examples/Advanced/PictureInPicture/CustomRender/PixelBufferRenderRTC.swift @@ -42,7 +42,7 @@ protocol CustomRenderRTCProtocol { @class SDKRenderRTC @abstract RTC management class, handle RTC connection, video view data management (view based on PixelBufferRenderView self-rendering), channel management */ -class CustomRenderRTC: NSObject, ObservableObject , CustomRenderRTCProtocol{ +class PixelBufferRenderRTC: NSObject, ObservableObject , CustomRenderRTCProtocol{ var videoFrameDelegte: AgoraVideoFrameDelegate? private var uid: UInt = 0 @@ -71,7 +71,7 @@ class CustomRenderRTC: NSObject, ObservableObject , CustomRenderRTCProtocol{ } } -extension CustomRenderRTC: AgoraVideoFrameDelegate { +extension PixelBufferRenderRTC: AgoraVideoFrameDelegate { func onCapture(_ videoFrame: AgoraOutputVideoFrame, sourceType: AgoraVideoSourceType) -> Bool { if let localView = localView, let pixelBuffer = videoFrame.pixelBuffer { localView.renderVideoPixelBuffer(pixelBuffer: pixelBuffer, width: videoFrame.width, height: videoFrame.height) diff --git a/iOS/APIExample-SwiftUI/APIExample-SwiftUI/Examples/Advanced/PictureInPicture/CustomRender/CustomRenderViewModel.swift b/iOS/APIExample-SwiftUI/APIExample-SwiftUI/Examples/Advanced/PictureInPicture/CustomRender/PixelBufferRenderViewModel.swift similarity index 94% rename from iOS/APIExample-SwiftUI/APIExample-SwiftUI/Examples/Advanced/PictureInPicture/CustomRender/CustomRenderViewModel.swift rename to iOS/APIExample-SwiftUI/APIExample-SwiftUI/Examples/Advanced/PictureInPicture/CustomRender/PixelBufferRenderViewModel.swift index 9d18dd720..e0520ab48 100644 --- a/iOS/APIExample-SwiftUI/APIExample-SwiftUI/Examples/Advanced/PictureInPicture/CustomRender/CustomRenderViewModel.swift +++ b/iOS/APIExample-SwiftUI/APIExample-SwiftUI/Examples/Advanced/PictureInPicture/CustomRender/PixelBufferRenderViewModel.swift @@ -11,10 +11,10 @@ import Foundation @class CustomRenderViewModel( @abstract This type has nothing to do with PIP and only simulates the implementation of rtc services for service reference and can be modified according to the service */ -class CustomRenderViewModel: NSObject, ObservableObject { +class PixelBufferRenderViewModel: NSObject, ObservableObject { @Published var remoteRenderViews: [PixelBufferCustomRenderView] = [] private var isJoined = false - var customRenderRtc: CustomRenderRTC + var customRenderRtc: PixelBufferRenderRTC var configs: [String: Any] private lazy var rtcConfig: AgoraRtcEngineConfig = { @@ -40,7 +40,7 @@ class CustomRenderViewModel: NSObject, ObservableObject { }() init(configs: [String: Any]) { - self.customRenderRtc = CustomRenderRTC() + self.customRenderRtc = PixelBufferRenderRTC() self.configs = configs super.init() } @@ -88,7 +88,7 @@ class CustomRenderViewModel: NSObject, ObservableObject { } } -extension CustomRenderViewModel: AgoraRtcEngineDelegate { +extension PixelBufferRenderViewModel: AgoraRtcEngineDelegate { func rtcEngine(_ engine: AgoraRtcEngineKit, didJoinChannel channel: String, withUid uid: UInt, elapsed: Int) { self.isJoined = true } diff --git a/iOS/APIExample-SwiftUI/APIExample-SwiftUI/Examples/Advanced/PictureInPicture/PictureInPicture.swift b/iOS/APIExample-SwiftUI/APIExample-SwiftUI/Examples/Advanced/PictureInPicture/PictureInPicture.swift index a34388bb1..5c7f45897 100644 --- a/iOS/APIExample-SwiftUI/APIExample-SwiftUI/Examples/Advanced/PictureInPicture/PictureInPicture.swift +++ b/iOS/APIExample-SwiftUI/APIExample-SwiftUI/Examples/Advanced/PictureInPicture/PictureInPicture.swift @@ -7,27 +7,21 @@ import SwiftUI -enum PipType { - case sdkRender, customRender -} - struct PipItem: Identifiable { let id = UUID() var name: String - var type: PipType } struct PictureInPictureEntry: View { var items: [PipItem] = [ - PipItem(name: "PIP Custom Render", type: .customRender), - PipItem(name: "PIP RTC SDK Render", type: .sdkRender) + PipItem(name: "Pixel Buffer Render"), ] var body: some View { List { ForEach(items) { item in NavigationLink(destination: { - let entry = PictureInPictureJoinEntry(pipType: item.type) + let entry = PictureInPictureJoinEntry() entry.navigationTitle(item.name) }) { Text(item.name) @@ -38,7 +32,6 @@ struct PictureInPictureEntry: View { } struct PictureInPictureJoinEntry: View { - var pipType: PipType @State private var channelName: String = "" @State private var isActive = false @State private var configs: [String: Any] = [:] @@ -54,22 +47,12 @@ struct PictureInPictureJoinEntry: View { Text("Join Channel") }.disabled(channelName.isEmpty) Spacer() - if pipType == .sdkRender { - if #available(iOS 15.0, *) { - NavigationLink(destination: sdkRenderView().navigationTitle(channelName).navigationBarTitleDisplayMode(.inline), isActive: $isActive) { - EmptyView() - } - } else { - // Fallback on earlier versions + if #available(iOS 15.0, *) { + NavigationLink(destination: customRenderView().navigationTitle(channelName).navigationBarTitleDisplayMode(.inline), isActive: $isActive) { + EmptyView() } } else { - if #available(iOS 15.0, *) { - NavigationLink(destination: customRenderView().navigationTitle(channelName).navigationBarTitleDisplayMode(.inline), isActive: $isActive) { - EmptyView() - } - } else { - // Fallback on earlier versions - } + // Fallback on earlier versions } Spacer() @@ -78,19 +61,14 @@ struct PictureInPictureJoinEntry: View { } @available(iOS 15.0, *) - private func customRenderView() -> CustomRenderExample { - return CustomRenderExample(configs: configs) - } - - @available(iOS 15.0, *) - private func sdkRenderView() -> SDKRenderExample{ - return SDKRenderExample(configs: configs) + private func customRenderView() -> PixelBufferRenderExample { + return PixelBufferRenderExample(configs: configs) } } struct PictureInPictureJoinEntryPreviews: PreviewProvider { static var previews: some View { - PictureInPictureJoinEntry(pipType: .customRender) + PictureInPictureJoinEntry() } } diff --git a/iOS/APIExample-SwiftUI/APIExample-SwiftUI/Examples/Advanced/PictureInPicture/SDKRender/SDKRenderExample.swift b/iOS/APIExample-SwiftUI/APIExample-SwiftUI/Examples/Advanced/PictureInPicture/SDKRender/SDKRenderExample.swift deleted file mode 100644 index 64641b951..000000000 --- a/iOS/APIExample-SwiftUI/APIExample-SwiftUI/Examples/Advanced/PictureInPicture/SDKRender/SDKRenderExample.swift +++ /dev/null @@ -1,91 +0,0 @@ -// -// SDKRenderExample.swift -// APIExample-SwiftUI -// -// Created by qinhui on 2024/8/13. -// - -import SwiftUI - -struct SDKRenderMockContainerView: View { - @ObservedObject var viewModel: SDKRenderViewModel - let localView = VideoView() - - var body: some View { - HStack { - localView - ForEach(viewModel.remoteRenderViews) { view in - view - } - } - } -} - -@available(iOS 15.0, *) -struct SDKRenderExample: View { - @State var configs: [String: Any] - - //mock data - @StateObject private var sdkRenderViewModel: SDKRenderViewModel - - //pip controller - @StateObject private var pipViewModel: PIPViewModel - - let myContainerView: SDKRenderMockContainerView - - init(configs: [String: Any]) { - _configs = State(initialValue: configs) - - let viewModel = SDKRenderViewModel(configs: configs) - _sdkRenderViewModel = StateObject(wrappedValue: viewModel) - - myContainerView = SDKRenderMockContainerView(viewModel: viewModel) - let pipSourceView = UIHostingController(rootView: myContainerView).view! - _pipViewModel = StateObject(wrappedValue: PIPViewModel(pipSourceView: pipSourceView)) - } - - var body: some View { - VStack(spacing: 30) { - PIPDisplayView(viewModel: pipViewModel) - .frame(maxWidth: .infinity, maxHeight: 200) - - Button { - pipViewModel.togglePiP() - } label: { - Text("PIP") - } - - Button { - pipViewModel.changePIPSize { - let pipSizes = [ - CGSize(width: 150, height: 300), - CGSize(width: 300, height: 150) - ] - let i = Int.random(in: 0.. = { - let table = NSHashTable(options: .weakMemory) - return table - }() - - func setupRtcEngine(rtcEngine: AgoraRtcEngineKit) { - self.rtcEngine = rtcEngine - } - - func setLocalView(localView: VideoUIView) { - guard let rtcEngine = rtcEngine else { return } - self.localView = localView - - let videoCanvas = AgoraRtcVideoCanvas() - videoCanvas.uid = localView.uid - // the view to be binded - videoCanvas.view = localView.videoView - videoCanvas.renderMode = .hidden - - rtcEngine.setupLocalVideo(videoCanvas) - // you have to call startPreview to see local video - rtcEngine.startPreview() - } - - func addRemoteRenderView(renderView: VideoUIView) { - guard let rtcEngine = rtcEngine else { return } - if renderView.uid == 0 { return } - // Only one remote video view is available for this - // tutorial. Here we check if there exists a surface - // view tagged as this uid. - let videoCanvas = AgoraRtcVideoCanvas() - videoCanvas.uid = renderView.uid - // the view to be binded - videoCanvas.view = renderView.videoView - videoCanvas.renderMode = .hidden - rtcEngine.setupRemoteVideo(videoCanvas) - - remoteRenderViews.add(renderView) - } - - func removeRemoteRenderView(renderView: VideoUIView) { - guard let rtcEngine = rtcEngine else { return } - - renderView.uid = 0 - - // to unlink your view from sdk, so that your view reference will be released - // note the video will stay at its last frame, to completely remove it - // you will need to remove the EAGL sublayer from your binded view - let videoCanvas = AgoraRtcVideoCanvas() - videoCanvas.uid = uid - // the view to be binded - videoCanvas.view = nil - videoCanvas.renderMode = .hidden - rtcEngine.setupRemoteVideo(videoCanvas) - - remoteRenderViews.remove(renderView) - } -} diff --git a/iOS/APIExample-SwiftUI/APIExample-SwiftUI/Examples/Advanced/PictureInPicture/SDKRender/SDKRenderViewModel.swift b/iOS/APIExample-SwiftUI/APIExample-SwiftUI/Examples/Advanced/PictureInPicture/SDKRender/SDKRenderViewModel.swift deleted file mode 100644 index c6ccf7c82..000000000 --- a/iOS/APIExample-SwiftUI/APIExample-SwiftUI/Examples/Advanced/PictureInPicture/SDKRender/SDKRenderViewModel.swift +++ /dev/null @@ -1,109 +0,0 @@ -// -// SDKRenderViewModel.swift -// APIExample-SwiftUI -// -// Created by qinhui on 2024/8/14. -// - -import Foundation - -/** - @class SDKRenderViewModel( - @abstract This type has nothing to do with PIP and only simulates the implementation of rtc services for service reference and can be modified according to the service - */ -class SDKRenderViewModel: NSObject, ObservableObject { - private var isJoined = false - var sdkRenderRtc: SDKRenderRTC - var configs: [String: Any] - - @Published var remoteRenderViews: [VideoView] = [] - - private lazy var rtcConfig: AgoraRtcEngineConfig = { - let config = AgoraRtcEngineConfig() - config.appId = KeyCenter.AppId - config.areaCode = .global - config.channelProfile = .liveBroadcasting - return config - }() - - private lazy var rtcEngine: AgoraRtcEngineKit = { - let engine = AgoraRtcEngineKit.sharedEngine(with: rtcConfig, delegate: self) - engine.setClientRole(.broadcaster) - engine.enableAudio() - engine.enableVideo() - engine.setVideoEncoderConfiguration(AgoraVideoEncoderConfiguration(size: CGSize(width: 960, height: 540), - frameRate: .fps15, - bitrate: AgoraVideoBitrateStandard, - orientationMode: .fixedPortrait, - mirrorMode: .auto)) - - return engine - }() - - init(configs: [String: Any]) { - self.sdkRenderRtc = SDKRenderRTC() - self.configs = configs - super.init() - } - - func setupRtcEngine(localView: VideoUIView) { - guard let channelName = configs["channelName"] as? String else { return } - let uid = UInt.random(in: 1..<100000) - rtcEngine.setDefaultAudioRouteToSpeakerphone(true) - - sdkRenderRtc.setupRtcEngine(rtcEngine: rtcEngine) - sdkRenderRtc.setLocalView(localView: localView) - - NetworkManager.shared.generateToken(channelName: channelName, success: { [weak self] token in - guard let self = self else { return } - - let option = AgoraRtcChannelMediaOptions() - option.publishCameraTrack = true - option.publishMicrophoneTrack = true - option.clientRoleType = .broadcaster - self.rtcEngine.joinChannel(byToken: token, channelId: channelName, uid: uid, mediaOptions: option) - }) - } - - func cleanRtc() { - rtcEngine.disableAudio() - rtcEngine.disableVideo() - if isJoined { - rtcEngine.stopPreview() - rtcEngine.leaveChannel(nil) - } - AgoraRtcEngineKit.destroy() - } - - func addRenderView(renderView: VideoView) { - remoteRenderViews.append(renderView) - - sdkRenderRtc.addRemoteRenderView(renderView: renderView.videoView) - } - - func removeRenderView(renderView: VideoView) { - if let index = remoteRenderViews.firstIndex(where: { $0.videoView.uid == renderView.videoView.uid }) { - remoteRenderViews.remove(at: index) - } - - sdkRenderRtc.removeRemoteRenderView(renderView: renderView.videoView) - } -} - -extension SDKRenderViewModel: AgoraRtcEngineDelegate { - func rtcEngine(_ engine: AgoraRtcEngineKit, didJoinChannel channel: String, withUid uid: UInt, elapsed: Int) { - self.isJoined = true - } - - func rtcEngine(_ engine: AgoraRtcEngineKit, didJoinedOfUid uid: UInt, elapsed: Int) { - let renderView = VideoView() - renderView.videoView.uid = uid - self.addRenderView(renderView: renderView) - } - - func rtcEngine(_ engine: AgoraRtcEngineKit, didOfflineOfUid uid: UInt, reason: AgoraUserOfflineReason) { - if let view = remoteRenderViews.first(where: { $0.videoView.uid == uid }) { - self.removeRenderView(renderView: view) - } - } -} diff --git a/iOS/APIExample/APIExample.xcodeproj/project.pbxproj b/iOS/APIExample/APIExample.xcodeproj/project.pbxproj index 44f29c857..f032fcf1d 100644 --- a/iOS/APIExample/APIExample.xcodeproj/project.pbxproj +++ b/iOS/APIExample/APIExample.xcodeproj/project.pbxproj @@ -228,8 +228,6 @@ E7AD0DE329C95EB500C9A4B0 /* PickerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E7AD0DE229C95EB500C9A4B0 /* PickerView.swift */; }; F728B9D72CA295D7007813BB /* PictureInPicture.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F728B9CD2CA295D7007813BB /* PictureInPicture.storyboard */; }; F728B9D82CA295D7007813BB /* ChannelViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F728B9CE2CA295D7007813BB /* ChannelViewController.swift */; }; - F728B9D92CA295D7007813BB /* CustomViewPIPService.swift in Sources */ = {isa = PBXBuildFile; fileRef = F728B9CF2CA295D7007813BB /* CustomViewPIPService.swift */; }; - F728B9DA2CA295D7007813BB /* CustomViewPIPViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F728B9D02CA295D7007813BB /* CustomViewPIPViewController.swift */; }; F728B9DB2CA295D7007813BB /* PIPBaseViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F728B9D22CA295D7007813BB /* PIPBaseViewController.swift */; }; F728B9DC2CA295D7007813BB /* PixelBufferPIPService.swift in Sources */ = {isa = PBXBuildFile; fileRef = F728B9D32CA295D7007813BB /* PixelBufferPIPService.swift */; }; F728B9DD2CA295D7007813BB /* PixelBufferPIPViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F728B9D42CA295D7007813BB /* PixelBufferPIPViewController.swift */; }; @@ -590,8 +588,6 @@ EB8CDD3F04870C6A31287732 /* Pods_audioFilter.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_audioFilter.framework; sourceTree = BUILT_PRODUCTS_DIR; }; F728B9CD2CA295D7007813BB /* PictureInPicture.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = PictureInPicture.storyboard; sourceTree = ""; }; F728B9CE2CA295D7007813BB /* ChannelViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChannelViewController.swift; sourceTree = ""; }; - F728B9CF2CA295D7007813BB /* CustomViewPIPService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CustomViewPIPService.swift; sourceTree = ""; }; - F728B9D02CA295D7007813BB /* CustomViewPIPViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CustomViewPIPViewController.swift; sourceTree = ""; }; F728B9D22CA295D7007813BB /* PIPBaseViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PIPBaseViewController.swift; sourceTree = ""; }; F728B9D32CA295D7007813BB /* PixelBufferPIPService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PixelBufferPIPService.swift; sourceTree = ""; }; F728B9D42CA295D7007813BB /* PixelBufferPIPViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PixelBufferPIPViewController.swift; sourceTree = ""; }; @@ -1273,7 +1269,6 @@ isa = PBXGroup; children = ( F728B9CE2CA295D7007813BB /* ChannelViewController.swift */, - F728B9D12CA295D7007813BB /* CustomViewPIPViewController */, F728B9CD2CA295D7007813BB /* PictureInPicture.storyboard */, F728B9D22CA295D7007813BB /* PIPBaseViewController.swift */, F728B9D62CA295D7007813BB /* PixelBufferPIPViewController */, @@ -1516,15 +1511,6 @@ path = Manager; sourceTree = ""; }; - F728B9D12CA295D7007813BB /* CustomViewPIPViewController */ = { - isa = PBXGroup; - children = ( - F728B9CF2CA295D7007813BB /* CustomViewPIPService.swift */, - F728B9D02CA295D7007813BB /* CustomViewPIPViewController.swift */, - ); - path = CustomViewPIPViewController; - sourceTree = ""; - }; F728B9D62CA295D7007813BB /* PixelBufferPIPViewController */ = { isa = PBXGroup; children = ( @@ -1613,7 +1599,6 @@ 1B6F6CF9B678035E221EAFDE /* [CP] Embed Pods Frameworks */, 0339BEBA25205B80007D4FDD /* Embed App Extensions */, E76F80122AF0A7A200CCB9D6 /* ShellScript */, - EA59815E58120166C6FD72B5 /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -1898,23 +1883,6 @@ shellPath = /bin/sh; shellScript = "\"${PODS_ROOT}/SwiftLint/swiftlint\" \n"; }; - EA59815E58120166C6FD72B5 /* [CP] Copy Pods Resources */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-APIExample/Pods-APIExample-resources-${CONFIGURATION}-input-files.xcfilelist", - ); - name = "[CP] Copy Pods Resources"; - outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-APIExample/Pods-APIExample-resources-${CONFIGURATION}-output-files.xcfilelist", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-APIExample/Pods-APIExample-resources.sh\"\n"; - showEnvVarsInLog = 0; - }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -1940,7 +1908,6 @@ E7A49D232907DD9A00F06DD4 /* EffectsCommonObject.m in Sources */, E7A49D652909111400F06DD4 /* BEHttpRequestProvider.mm in Sources */, E7A49CFB29029E0000F06DD4 /* ThirdBeautify.swift in Sources */, - F728B9D92CA295D7007813BB /* CustomViewPIPService.swift in Sources */, 036CBA3F2519186300D74FAD /* StreamEncryption.swift in Sources */, E7A49D5129090FCC00F06DD4 /* BEEffectManager.mm in Sources */, E76347D32AAEF4AF005D130F /* BeautyAPI.m in Sources */, @@ -2044,7 +2011,6 @@ E7A49CFE29029E0000F06DD4 /* FUBeautifyVC.m in Sources */, E77902672A484A8A008791AD /* KFMP4Demuxer.m in Sources */, 0385767E2521E5A0003C369A /* MediaChannelRelay.swift in Sources */, - F728B9DA2CA295D7007813BB /* CustomViewPIPViewController.swift in Sources */, 03BCEC762449EB5000ED7177 /* LogViewController.swift in Sources */, E7A49CBA29011E7500F06DD4 /* MutliCamera.swift in Sources */, 0339D6D624E91CEB008739CD /* QuickSwitchChannel.swift in Sources */, @@ -2639,7 +2605,7 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = YS397FG5PA; + DEVELOPMENT_TEAM = G726234S43; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = "$(inherited)"; INFOPLIST_FILE = "Agora-ScreenShare-Extension/Info.plist"; @@ -2673,7 +2639,7 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = YS397FG5PA; + DEVELOPMENT_TEAM = G726234S43; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = "$(inherited)"; INFOPLIST_FILE = "Agora-ScreenShare-Extension/Info.plist"; @@ -2829,7 +2795,7 @@ CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 2; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - DEVELOPMENT_TEAM = YS397FG5PA; + DEVELOPMENT_TEAM = G726234S43; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = "$(inherited)"; INFOPLIST_FILE = APIExample/Info.plist; @@ -2900,7 +2866,7 @@ CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 2; - DEVELOPMENT_TEAM = YS397FG5PA; + DEVELOPMENT_TEAM = G726234S43; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = "$(inherited)"; INFOPLIST_FILE = APIExample/Info.plist; @@ -2969,7 +2935,7 @@ CURRENT_PROJECT_VERSION = 1; DEAD_CODE_STRIPPING = NO; DEFINES_MODULE = YES; - DEVELOPMENT_TEAM = YS397FG5PA; + DEVELOPMENT_TEAM = G726234S43; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; @@ -3006,7 +2972,7 @@ CURRENT_PROJECT_VERSION = 1; DEAD_CODE_STRIPPING = NO; DEFINES_MODULE = YES; - DEVELOPMENT_TEAM = YS397FG5PA; + DEVELOPMENT_TEAM = G726234S43; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; diff --git a/iOS/APIExample/APIExample/Examples/Advanced/PictureInPicture/ChannelViewController.swift b/iOS/APIExample/APIExample/Examples/Advanced/PictureInPicture/ChannelViewController.swift index 49e931b0c..1bbe8eda1 100644 --- a/iOS/APIExample/APIExample/Examples/Advanced/PictureInPicture/ChannelViewController.swift +++ b/iOS/APIExample/APIExample/Examples/Advanced/PictureInPicture/ChannelViewController.swift @@ -6,6 +6,7 @@ // import UIKit +import SnapKit class ChannelViewController: UIViewController { lazy var textField: UITextField = { diff --git a/iOS/APIExample/APIExample/Examples/Advanced/PictureInPicture/CustomViewPIPViewController/CustomViewPIPService.swift b/iOS/APIExample/APIExample/Examples/Advanced/PictureInPicture/CustomViewPIPViewController/CustomViewPIPService.swift deleted file mode 100644 index 4e99795c7..000000000 --- a/iOS/APIExample/APIExample/Examples/Advanced/PictureInPicture/CustomViewPIPViewController/CustomViewPIPService.swift +++ /dev/null @@ -1,169 +0,0 @@ -// -// RtcManager.swift -// PIPDemo -// -// Created by qinhui on 2024/8/7. -// - -import Foundation -import AgoraRtcKit - -class CustomViewPIPService: NSObject { - var rtcEngineDelegate: AgoraRtcEngineDelegate? - var videoFrameDelegte: AgoraVideoFrameDelegate? - - weak var localView: UIView? - weak var remoteView: UIView? - var channelId: String - - private lazy var rtcConfig: AgoraRtcEngineConfig = { - let config = AgoraRtcEngineConfig() - config.appId = KeyCenter.AppId - config.areaCode = .global - config.channelProfile = .liveBroadcasting - return config - }() - - private lazy var rtcEngine: AgoraRtcEngineKit = { - let engine = AgoraRtcEngineKit.sharedEngine(with: rtcConfig, delegate: self) - engine.setClientRole(.broadcaster) - engine.enableAudio() - engine.enableVideo() - engine.setVideoEncoderConfiguration(AgoraVideoEncoderConfiguration(size: CGSize(width: 960, height: 540), - frameRate: .fps15, - bitrate: AgoraVideoBitrateStandard, - orientationMode: .adaptative, - mirrorMode: .auto)) - engine.setVideoFrameDelegate(self) - return engine - }() - - init(localView: UIView, remoteView: UIView, channelId: String) { - self.localView = localView - self.remoteView = remoteView - self.channelId = channelId - - super.init() - - setupRtcEngin() - } - - private func setupRtcEngin() { - let videoCanvas = AgoraRtcVideoCanvas() - videoCanvas.uid = 0 - videoCanvas.view = localView - videoCanvas.renderMode = .hidden - - rtcEngine.setupLocalVideo(videoCanvas) - rtcEngine.startPreview() - rtcEngine.setDefaultAudioRouteToSpeakerphone(true) - rtcEngine.setVideoFrameDelegate(self) - - let option = AgoraRtcChannelMediaOptions() - option.publishCameraTrack = true - option.publishMicrophoneTrack = true - option.clientRoleType = .broadcaster - - NetworkManager.shared.generateToken(channelName: channelId, success: { [weak self] token in - guard let self = self else { return } - - let result = self.rtcEngine.joinChannel(byToken: token, channelId: self.channelId, uid: 0, mediaOptions: option) - if result != 0 { - ToastView.showWait(text: "joinChannel call failed: \(result), please check your params", view: nil) - } - }) - } - - func disable() { - rtcEngine.disableAudio() - rtcEngine.disableVideo() - } - - func leave() { - rtcEngine.stopPreview() - rtcEngine.leaveChannel(nil) - } - -} - -extension CustomViewPIPService: AgoraRtcEngineDelegate { - func rtcEngine(_ engine: AgoraRtcEngineKit, didOccur errorType: AgoraEncryptionErrorType) { - rtcEngineDelegate?.rtcEngine?(engine, didOccur: errorType) - } - - func rtcEngine(_ engine: AgoraRtcEngineKit, didJoinChannel channel: String, withUid uid: UInt, elapsed: Int) { - rtcEngineDelegate?.rtcEngine?(engine, didJoinChannel: channel, withUid: uid, elapsed: elapsed) - } - - /// callback when a remote user is joinning the channel, note audience in live broadcast mode will NOT trigger this event - /// @param uid uid of remote joined user - /// @param elapsed time elapse since current sdk instance join the channel in ms - func rtcEngine(_ engine: AgoraRtcEngineKit, didJoinedOfUid uid: UInt, elapsed: Int) { - // Only one remote video view is available for this - // tutorial. Here we check if there exists a surface - // view tagged as this uid. - let videoCanvas = AgoraRtcVideoCanvas() - videoCanvas.uid = uid - // the view to be binded - videoCanvas.view = remoteView - videoCanvas.renderMode = .hidden - rtcEngine.setupRemoteVideo(videoCanvas) - - rtcEngineDelegate?.rtcEngine?(engine, didJoinedOfUid: uid, elapsed: elapsed) - } - - /// callback when a remote user is leaving the channel, note audience in live broadcast mode will NOT trigger this event - /// @param uid uid of remote joined user - /// @param reason reason why this user left, note this event may be triggered when the remote user - /// become an audience in live broadcasting profile - func rtcEngine(_ engine: AgoraRtcEngineKit, didOfflineOfUid uid: UInt, reason: AgoraUserOfflineReason) { - let videoCanvas = AgoraRtcVideoCanvas() - videoCanvas.uid = uid - // the view to be binded - videoCanvas.view = nil - videoCanvas.renderMode = .hidden - rtcEngine.setupRemoteVideo(videoCanvas) - - rtcEngineDelegate?.rtcEngine?(engine, didOfflineOfUid: uid, reason: reason) - } - - func rtcEngine(_ engine: AgoraRtcEngineKit, connectionChangedTo state: AgoraConnectionState, reason: AgoraConnectionChangedReason) { - rtcEngineDelegate?.rtcEngine?(engine, connectionChangedTo: state, reason: reason) - } - - /// Reports the statistics of the current call. The SDK triggers this callback once every two seconds after the user joins the channel. - /// @param stats stats struct - func rtcEngine(_ engine: AgoraRtcEngineKit, reportRtcStats stats: AgoraChannelStats) { - rtcEngineDelegate?.rtcEngine?(engine, reportRtcStats: stats) - } - - /// Reports the statistics of the uploading local audio streams once every two seconds. - /// @param stats stats struct - func rtcEngine(_ engine: AgoraRtcEngineKit, localAudioStats stats: AgoraRtcLocalAudioStats) { - rtcEngineDelegate?.rtcEngine?(engine, localAudioStats: stats) - } - - /// Reports the statistics of the video stream from each remote user/host. - /// @param stats stats struct - func rtcEngine(_ engine: AgoraRtcEngineKit, remoteVideoStats stats: AgoraRtcRemoteVideoStats) { - rtcEngineDelegate?.rtcEngine?(engine, remoteVideoStats: stats) - } - - /// Reports the statistics of the audio stream from each remote user/host. - /// @param stats stats struct for current call statistics - func rtcEngine(_ engine: AgoraRtcEngineKit, remoteAudioStats stats: AgoraRtcRemoteAudioStats) { - rtcEngineDelegate?.rtcEngine?(engine, remoteAudioStats: stats) - } -} - -extension CustomViewPIPService: AgoraVideoFrameDelegate { - func onCapture(_ videoFrame: AgoraOutputVideoFrame, sourceType: AgoraVideoSourceType) -> Bool { - print("") - return true - } - - func onRenderVideoFrame(_ videoFrame: AgoraOutputVideoFrame, uid: UInt, channelId: String) -> Bool { - print("") - return true - } -} diff --git a/iOS/APIExample/APIExample/Examples/Advanced/PictureInPicture/CustomViewPIPViewController/CustomViewPIPViewController.swift b/iOS/APIExample/APIExample/Examples/Advanced/PictureInPicture/CustomViewPIPViewController/CustomViewPIPViewController.swift deleted file mode 100644 index ebe0ac770..000000000 --- a/iOS/APIExample/APIExample/Examples/Advanced/PictureInPicture/CustomViewPIPViewController/CustomViewPIPViewController.swift +++ /dev/null @@ -1,234 +0,0 @@ -// -// VideoViewController.swift -// PIPDemo -// -// Created by qinhui on 2024/8/7. -// - -import UIKit -import SnapKit -import AgoraRtcKit -import AVKit - -@available(iOS 15.0, *) -class CustomViewPIPViewController: PIPBaseViewController { - private let containerH = 250.0 - private var isJoined: Bool = false - private var pipController: AVPictureInPictureController? - private var videoCallbackController: AVPictureInPictureVideoCallViewController? - private var backgroundTask: UIBackgroundTaskIdentifier = .invalid - - private var pipSizes = [ - CGSize(width: 150, height: 300), - CGSize(width: 300, height: 150) - ] - - private lazy var pipButton: UIButton = { - let button = UIButton(type: .custom) - button.setTitle("画中画", for: .normal) - button.addTarget(self, action: #selector(pipAction), for: .touchUpInside) - button.backgroundColor = .purple - return button - }() - - private lazy var sizeButton: UIButton = { - let button = UIButton(type: .custom) - button.setTitle("切换尺寸", for: .normal) - button.addTarget(self, action: #selector(sizeAction), for: .touchUpInside) - button.backgroundColor = .red - - return button - }() - - private lazy var localVideoView: UIView = { - let view = UIView() - view.backgroundColor = .green - return view - }() - - private lazy var remoteVideoView: UIView = { - let view = UIView() - view.backgroundColor = .orange - return view - }() - - private lazy var videoContainerView: UIView = { - let view = UIView() - view.backgroundColor = .purple - return view - }() - - private var rtcService: CustomViewPIPService! - - override func viewDidLoad() { - super.viewDidLoad() - view.backgroundColor = .white - initRtc() - configViews() - if AVPictureInPictureController.isPictureInPictureSupported() { - configPIPViewController() - } - } - - override func viewWillDisappear(_ animated: Bool) { - super.viewWillDisappear(animated) - guard let pipController = pipController else { return } - pipController.stopPictureInPicture() - } - - override func viewDidDisappear(_ animated: Bool) { - super.viewDidDisappear(animated) - rtcService.disable() - - if isJoined { - rtcService.leave() - } - } -} - -@available(iOS 15.0, *) -extension CustomViewPIPViewController { - @objc func pipAction() { - guard let pipController = pipController else { return } - - if pipController.isPictureInPictureActive { - pipController.stopPictureInPicture() - } else { - pipController.startPictureInPicture() - } - } - - @objc func sizeAction() { - guard let videoCallbackController = videoCallbackController else { return } - - let i = Int.random(in: 0..] = { if #available(iOS 15.0, *) { return [ - Model(title: "SDK 渲染", cls: CustomViewPIPViewController.self), Model(title: "多人视频自渲染", cls: PixelBufferPIPViewController.self) ] } else { diff --git a/iOS/APIExample/APIExample/Examples/Advanced/PictureInPicture/PixelBufferPIPViewController/PixelBufferPIPViewController.swift b/iOS/APIExample/APIExample/Examples/Advanced/PictureInPicture/PixelBufferPIPViewController/PixelBufferPIPViewController.swift index d501f8a46..c65f20538 100644 --- a/iOS/APIExample/APIExample/Examples/Advanced/PictureInPicture/PixelBufferPIPViewController/PixelBufferPIPViewController.swift +++ b/iOS/APIExample/APIExample/Examples/Advanced/PictureInPicture/PixelBufferPIPViewController/PixelBufferPIPViewController.swift @@ -256,9 +256,14 @@ extension PixelBufferPIPViewController: AgoraVideoFrameDelegate { func onRenderVideoFrame(_ videoFrame: AgoraOutputVideoFrame, uid: UInt, channelId: String) -> Bool { if let view = displayViews.allObjects.first(where: { $0.uid == uid }) { - view.renderFromVideoFrameData(videoData: videoFrame, uid: Int(uid)) + if let pixelBuffer = videoFrame.pixelBuffer { + view.renderVideoPixelBuffer(pixelBuffer: pixelBuffer, width: videoFrame.width, height: videoFrame.height) + } else { + view.renderFromVideoFrameData(videoData: videoFrame, uid: Int(uid)) + } } return true } + }