Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion SwiftUIExample/SwiftUIExample.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
8758EAB2294CB60B00FA56B3 /* VideoSDK.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8758EAB1294CB60B00FA56B3 /* VideoSDK.swift */; };
8758EAB4294CB85A00FA56B3 /* VideoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8758EAB3294CB85A00FA56B3 /* VideoView.swift */; };
8758EAB7294CBF8E00FA56B3 /* SwiftUIExampleApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8758EAB6294CBF8E00FA56B3 /* SwiftUIExampleApp.swift */; };
87D7852E29659DF200C5EF49 /* Models.swift in Sources */ = {isa = PBXBuildFile; fileRef = 87D7852D29659DF200C5EF49 /* Models.swift */; };
9132155B26B03E76002694A8 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 9132155A26B03E76002694A8 /* Assets.xcassets */; };
9132155E26B03E76002694A8 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9132155C26B03E76002694A8 /* LaunchScreen.storyboard */; };
/* End PBXBuildFile section */
Expand All @@ -21,6 +22,7 @@
8758EAB1294CB60B00FA56B3 /* VideoSDK.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoSDK.swift; sourceTree = "<group>"; };
8758EAB3294CB85A00FA56B3 /* VideoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoView.swift; sourceTree = "<group>"; };
8758EAB6294CBF8E00FA56B3 /* SwiftUIExampleApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwiftUIExampleApp.swift; sourceTree = "<group>"; };
87D7852D29659DF200C5EF49 /* Models.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Models.swift; sourceTree = "<group>"; };
9132154E26B03E74002694A8 /* SwiftUIExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SwiftUIExample.app; sourceTree = BUILT_PRODUCTS_DIR; };
9132155A26B03E76002694A8 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
9132155D26B03E76002694A8 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
Expand All @@ -43,11 +45,20 @@
isa = PBXGroup;
children = (
8758EAB1294CB60B00FA56B3 /* VideoSDK.swift */,
8758EAB3294CB85A00FA56B3 /* VideoView.swift */,
87D7852F2965A16D00C5EF49 /* Internals */,
);
path = 100ms;
sourceTree = "<group>";
};
87D7852F2965A16D00C5EF49 /* Internals */ = {
isa = PBXGroup;
children = (
87D7852D29659DF200C5EF49 /* Models.swift */,
8758EAB3294CB85A00FA56B3 /* VideoView.swift */,
);
path = Internals;
sourceTree = "<group>";
};
9132154526B03E74002694A8 = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -156,6 +167,7 @@
8758EAB7294CBF8E00FA56B3 /* SwiftUIExampleApp.swift in Sources */,
8758EAB0294CB5EC00FA56B3 /* ContentView.swift in Sources */,
8758EAB2294CB60B00FA56B3 /* VideoSDK.swift in Sources */,
87D7852E29659DF200C5EF49 /* Models.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
154 changes: 154 additions & 0 deletions SwiftUIExample/SwiftUIExample/100ms/Internals/Models.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
//
// Models.swift
// SwiftUIExample
//
// Created by Pawan Dixit on 04/01/2023.
//

import HMSSDK

class HMSPeerTileModel: ObservableObject, HMSUpdateListener {

static let shared = HMSPeerTileModel()

@Published var peerSet = Set<HMSPeerModel>()

func on(join room: HMSRoom) {
}

func on(room: HMSRoom, update: HMSRoomUpdate) {

}

func on(peer: HMSPeer, update: HMSPeerUpdate) {
}

func on(track: HMSTrack, update: HMSTrackUpdate, for peer: HMSPeer) {

guard let _ = (peerSet.first{$0.peer == peer}) else { return }

switch update {
case .trackAdded:
peerSet = Set(peerSet.map { peerModel in
if peerModel.peer == peer {
var peerModelCopy = peerModel
peerModelCopy.tracks.append(HMSTrackModel(track: track, isMuted: track.isMute()))
return peerModelCopy
}
else {
return peerModel
}
})

case .trackRemoved:
peerSet = Set(peerSet.map { peerModel in
if peerModel.peer == peer {
var peerModelCopy = peerModel
peerModelCopy.tracks.removeAll{$0.track == track}
return peerModelCopy
}
else {
return peerModel
}
})
case .trackMuted:

peerSet = Set(peerSet.map { peerModel in
if peerModel.peer == peer {
var peerModelCopy = peerModel
peerModelCopy.tracks = peerModel.tracks.map {
if $0.track == track {
var copy = $0
copy.isMuted = true
return copy
}
else {
return $0
}
}

return peerModelCopy
}
else {
return peerModel
}
})


case.trackUnmuted:

peerSet = Set(peerSet.map { peerModel in
if peerModel.peer == peer {
var peerModelCopy = peerModel
peerModelCopy.tracks = peerModel.tracks.map {
if $0.track == track {
var copy = $0
copy.isMuted = false
return copy
}
else {
return $0
}
}

return peerModelCopy
}
else {
return peerModel
}
})
default:
break
}
}

func on(error: Error) {
print(error.localizedDescription)
}

func on(message: HMSMessage) {

}

func on(updated speakers: [HMSSpeaker]) {

}

func onReconnecting() {

}

func onReconnected() {

}
}

struct HMSPeerModel: Equatable, Hashable {

var peer: HMSPeer

var tracks = [HMSTrackModel]()

init(peer: HMSPeer, tracks: [HMSTrack]) {
self.peer = peer
self.tracks.append(contentsOf: tracks.map{HMSTrackModel(track: $0, isMuted: $0.isMute())})
}

public func hash(into hasher: inout Hasher) {
return hasher.combine(peer)
}

static func == (lhs: HMSPeerModel, rhs: HMSPeerModel) -> Bool {
lhs.peer == rhs.peer
}
}

struct HMSTrackModel {
let track: HMSTrack
var isMuted: Bool

init(track: HMSTrack, isMuted: Bool) {
self.track = track
self.isMuted = isMuted
}
}
92 changes: 92 additions & 0 deletions SwiftUIExample/SwiftUIExample/100ms/Internals/VideoView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
//
// HMSViewRepresentable.swift
// SwiftUIExample
//
// Created by Pawan Dixit on 16/12/2022.
//

import SwiftUI
import HMSSDK

struct VideoView: UIViewRepresentable {
var track: HMSVideoTrack

func makeUIView(context: Context) -> HMSVideoView {

let videoView = HMSVideoView()
videoView.setVideoTrack(track)
videoView.videoContentMode = .scaleAspectFill
return videoView
}

func updateUIView(_ videoView: HMSVideoView, context: Context) {}
}


@available(iOS 13.0.0, *)
struct HMSPeerTile: View {

@ObservedObject var model = HMSPeerTileModel.shared

let peer: HMSPeer

var peerModel: HMSPeerModel? {
model.peerSet.first{$0.peer == peer}
}

init(peer: HMSPeer) {
self.peer = peer
}

var audioTrack: HMSAudioTrack? {
peer.audioTrack
}

var localAudioTrack: HMSLocalAudioTrack? {
guard let track = peer.audioTrack as? HMSLocalAudioTrack else { return nil }
return (peerModel?.tracks.first{$0.track.trackId == track.trackId})?.track as? HMSLocalAudioTrack
}

var videoTrackModel: HMSTrackModel? {
return (peerModel?.tracks.first{$0.track.trackId == peer.videoTrack?.trackId})
}

var isLocal: Bool {
peer.isLocal
}

var body: some View {
ZStack {

if let videoTrackModel = videoTrackModel, !videoTrackModel.isMuted {
VideoView(track: videoTrackModel.track as! HMSVideoTrack)
.edgesIgnoringSafeArea(.all)
}
else {
Image(systemName: "person")
}

if let localAudioTrack = localAudioTrack {
VStack {
Image(systemName: "mic")
.onTapGesture {
localAudioTrack.setMute(!localAudioTrack.isMute())
}
Spacer(minLength: 0)
}
}
}
.onAppear() {
let tracks = [peer.videoTrack, peer.audioTrack].compactMap{$0}
model.peerSet.insert(HMSPeerModel(peer: peer, tracks: tracks))
}
.onDisappear() {
if let peerToRemove = Array(model.peerSet).first(where: {$0.peer == peer}) {
model.peerSet.remove(peerToRemove)
}
else {
assertionFailure()
}
}
}
}
29 changes: 12 additions & 17 deletions SwiftUIExample/SwiftUIExample/100ms/VideoSDK.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,26 @@ import HMSSDK

class VideoSDK: ObservableObject {

static let shared = VideoSDK()

let hmsSDK = HMSSDK.build()
@Published var tracks = [HMSVideoTrack]()
@Published var peers = [HMSPeer]()

@Published var isJoined = false

func joinRoom() {
let config = HMSConfig(userName:"John Doe", authToken: "insert token here")
let config = HMSConfig(userName:"John Doe", authToken: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhY2Nlc3Nfa2V5IjoiNjFmMTc3NDE0ZjZiMDIxOGYyM2I3Yzg4Iiwicm9vbV9pZCI6IjYxZjE3N2Q2ZDg1YmYwNWVlNGUxN2U0NiIsInVzZXJfaWQiOiJhZ2hoeWNxciIsInJvbGUiOiJzdGFnZSIsImp0aSI6IjA1NTM4YjZjLTUxZDEtNGE0Ni1hYmM5LThiMjljOTQyZTBmMiIsInR5cGUiOiJhcHAiLCJ2ZXJzaW9uIjoyLCJleHAiOjE2NzI4MzU4OTd9.bxPM6LTuV1_r4NsnjRRMRcmdN_ePqFnbmfLzthcIqHU")
hmsSDK.join(config: config, delegate: self)
hmsSDK.add(delegate: HMSPeerTileModel.shared)
}
}

extension VideoSDK: HMSUpdateListener {
func on(join room: HMSRoom) {
isJoined = true
if let peer = hmsSDK.localPeer {
peers.append(peer)
}
}

func on(room: HMSRoom, update: HMSRoomUpdate) {
Expand All @@ -31,28 +38,16 @@ extension VideoSDK: HMSUpdateListener {

func on(peer: HMSPeer, update: HMSPeerUpdate) {
switch update {
case .peerJoined:
peers.append(peer)
case .peerLeft:
if let videoTrack = peer.videoTrack {
tracks.removeAll { $0 == videoTrack }
}
peers.removeAll { $0 == peer }
default:
break
}
}

func on(track: HMSTrack, update: HMSTrackUpdate, for peer: HMSPeer) {
switch update {
case .trackAdded:
if let videoTrack = track as? HMSVideoTrack {
tracks.append(videoTrack)
}
case .trackRemoved:
if let videoTrack = track as? HMSVideoTrack {
tracks.removeAll { $0 == videoTrack }
}
default:
break
}
}

func on(error: Error) {
Expand Down
23 changes: 0 additions & 23 deletions SwiftUIExample/SwiftUIExample/100ms/VideoView.swift

This file was deleted.

6 changes: 3 additions & 3 deletions SwiftUIExample/SwiftUIExample/ContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,16 @@ import HMSSDK

struct ContentView: View {

@StateObject var videoSDK = VideoSDK()
@StateObject var videoSDK = VideoSDK.shared
@State var isJoining = false

var body: some View {

Group {
if videoSDK.isJoined {
List {
ForEach(videoSDK.tracks, id: \.self) { track in
VideoView(track: track)
ForEach(videoSDK.peers, id: \.self) { peer in
HMSPeerTile(peer: peer)
.frame(height: 300)
}
}
Expand Down