🦁
SwiftUIでSkyWayの映像を表示する(SwiftUIでSKWVideoを使う方法)
SwiftUIでSkyWayの映像を表示してみました。SkyWayはWebRTCのプラットフォームです、iOSのSDKが提供されています。
iOSのSDKには映像を表示するためのSKWVideo
というクラスが提供されています。これはUIKitで使用することを想定されたコンポーネントで、SwiftUIから使用する方法がわかりませんでした。
UIViewRepresentable
を使うとSwiftUIでUIKitのコンポーネントを表示することができるのでSKWVideo
に対して適用したところ表示できました。画像では丸くくり抜いたり影をつけています。
カスタムビューのコード全体です、UIViewRepresentableを継承したVideoView
を作成します。
struct VideoView: UIViewRepresentable {
typealias UIViewType = SKWVideo
let stream: SKWMediaStream
let videoView = UIViewType()
func makeUIView(context: Context) -> UIViewType {
return videoView
}
func updateUIView(_ uiView: UIViewType, context: Context) {
stream.addVideoRenderer(uiView, track: 0)
}
final class Coordinator: NSObject {
let parent: VideoView
init(_ parent: VideoView) {
self.parent = parent
}
}
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
static func dismantleUIView(_ uiView: UIViewType, coordinator: Coordinator) {
// perform additional clean-up work related custom view
coordinator.parent.stream.removeVideoRenderer(uiView, track: 0)
}
}
ポイント
- Viewが作成されるときに
makeUIView
が呼ばれるのでSKWVideoのインスタンスをreturnする - Viewが表示(更新)されるときに
updateUIView
が呼ばれるのでstreamをaddVideoRendererする - Viewが取り除かれるときに
dismantleUIView
が呼ばれるのでremoveVideoRendererを呼び出す- streamにアクセスするために
makeCoordinator
でCordinatorを作成している
- streamにアクセスするために
本体側、Viewを表示する側のコードです。
struct ContentView: View {
@State var peer: SKWPeer?
@State var localStream: SKWMediaStream?
var body: some View {
VStack {
Text("Hello, world!")
.padding()
if let peer = peer {
Button("getUserMedia") {
if localStream == nil {
SKWNavigator.initialize(peer)
let constraints = SKWMediaConstraints()
constraints.minFrameRate = 30
localStream = SKWNavigator.getUserMedia(constraints)
} else {
localStream?.close()
localStream = nil
}
}
if let localStream = localStream {
VideoView(stream: localStream)
.clipShape(Circle())
.overlay(Circle().stroke(Color.gray, lineWidth: 4))
.shadow(radius: 7)
.padding()
}
}
}
.onAppear {
let option = SKWPeerOption.init()
option.key = skywayAPIKey
option.domain = skywayDomain
self.peer = SKWPeer(options: option)
}
}
}
ポイント
-
peer
を作成する -
SKWNavigator.getUserMedia
を呼び出してlocalStreamを取得する -
VideoView(stream: localStream)
でViewを宣言する
カスタムビューはSwiftUIのViewなのでclipShape
などを使って見た目を加工することができます。
Discussion