Skip to content

Commit

Permalink
Merge pull request #49 from 100mslive/0.4.1Release
Browse files Browse the repository at this point in the history
0.4.1 Release
  • Loading branch information
gzerad authored Sep 9, 2022
2 parents 0b7f46a + 6520858 commit b794a48
Show file tree
Hide file tree
Showing 12 changed files with 165 additions and 39 deletions.
7 changes: 4 additions & 3 deletions Example/HMSSDKExample/Meeting/Chat/ChatViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ final class ChatViewController: UIViewController {

sender.isEnabled = false

let messageHandler: ((HMSMessage?, HMSError?) -> Void) = { [weak self, weak sender] sentMessage, error in
let messageHandler: ((HMSMessage?, Error?) -> Void) = { [weak self, weak sender] sentMessage, error in
sender?.isEnabled = true

if let sentMessage = sentMessage {
Expand All @@ -171,11 +171,12 @@ final class ChatViewController: UIViewController {
}
}

private func showMessageSendError(_ error: HMSError) {
private func showMessageSendError(_ error: Error) {
guard let error = error as? HMSError else { return }
let title = "Could Not Send a Message"

let alertController = UIAlertController(title: title,
message: error.message,
message: error.localizedDescription,
preferredStyle: .alert)

alertController.addAction(UIAlertAction(title: "OK", style: .cancel))
Expand Down
77 changes: 73 additions & 4 deletions Example/HMSSDKExample/Meeting/HLSStreamViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,16 @@
import UIKit
import AVFoundation

class HLSStreamViewController: UIViewController {
class HLSStreamViewController: UIViewController, AVPlayerItemMetadataCollectorPushDelegate {

var player: AVPlayer?
var playerView: PlayerView!
var metadataView: UILabel!
var metadataCollector: AVPlayerItemMetadataCollector!
var retriesLeft = 0
var playerItem: AVPlayerItem?
var currentMetadataGroup: AVDateRangeMetadataGroup?
var metadataGroups = [AVDateRangeMetadataGroup]()

var streamURL: URL? {
didSet {
Expand All @@ -26,12 +31,25 @@ class HLSStreamViewController: UIViewController {
}

override func loadView() {
let containerView = UIView()
view = containerView

playerView = PlayerView()
view = playerView
containerView.addConstrained(subview: playerView)

metadataView = UILabel()
containerView.addSubview(metadataView)
metadataView.translatesAutoresizingMaskIntoConstraints = false
metadataView.backgroundColor = .lightGray
metadataView.textColor = .black
metadataView.textAlignment = .center
metadataView.bottomAnchor.constraint(equalTo: playerView.bottomAnchor).isActive = true
metadataView.leftAnchor.constraint(equalTo: playerView.leftAnchor).isActive = true
metadataView.rightAnchor.constraint(equalTo: playerView.rightAnchor).isActive = true
metadataView.heightAnchor.constraint(equalToConstant: 60.0).isActive = true
metadataView.isHidden = true
}

var playerItem: AVPlayerItem?

override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(applicationDidEnterBackground(_:)), name: UIApplication.didEnterBackgroundNotification, object: nil)
Expand All @@ -58,10 +76,15 @@ class HLSStreamViewController: UIViewController {
let assetKeys = [
"playable"
]

metadataCollector = AVPlayerItemMetadataCollector()
metadataCollector.setDelegate(self, queue: DispatchQueue.main)

// Create a new AVPlayerItem with the asset and an
// array of asset keys to be automatically loaded
let item = AVPlayerItem(asset: asset,
automaticallyLoadedAssetKeys: assetKeys)
item.add(metadataCollector)

// Register as an observer of the player item's status property
item.addObserver(self,
Expand All @@ -73,6 +96,9 @@ class HLSStreamViewController: UIViewController {
if player == nil {
player = AVPlayer(playerItem: item)
playerView.player = player
player?.addPeriodicTimeObserver(forInterval: CMTime(seconds: 1.0, preferredTimescale: CMTimeScale(NSEC_PER_SEC)), queue: .main, using: { [weak self] time in
self?.updateMetadataView(for: time)
})
} else {
player?.replaceCurrentItem(with: item)
}
Expand All @@ -81,6 +107,35 @@ class HLSStreamViewController: UIViewController {
func stop() {
player?.pause()
}

func updateMetadataView(for currentTime: CMTime) {
hideCurrentMetadataViewIfNeeded()

guard currentMetadataGroup == nil, let playerItem = playerItem else { return }

for group in metadataGroups {
if group.shouldShow(for: playerItem) {
showMetadataView(for: group)
break
}
}
}

func showMetadataView(for group: AVDateRangeMetadataGroup) {
guard currentMetadataGroup != group else { return }

currentMetadataGroup = group
metadataView.isHidden = false
metadataView.text = group.items.first?.stringValue
}

func hideCurrentMetadataViewIfNeeded() {
guard let currentMetadataGroup = currentMetadataGroup,
let playerItem = playerItem,
!currentMetadataGroup.shouldShow(for: playerItem) else { return }
self.currentMetadataGroup = nil
metadataView.isHidden = true
}

override func observeValue(forKeyPath keyPath: String?,
of object: Any?,
Expand Down Expand Up @@ -132,6 +187,13 @@ class HLSStreamViewController: UIViewController {
@objc func applicationDidBecomeActive(_ notificiation: Notification) {
playerView.player = player
}

func metadataCollector(_ metadataCollector: AVPlayerItemMetadataCollector,
didCollect metadataGroups: [AVDateRangeMetadataGroup],
indexesOfNewGroups: IndexSet,
indexesOfModifiedGroups: IndexSet) {
self.metadataGroups = metadataGroups
}
}

class PlayerView: UIView {
Expand All @@ -148,3 +210,10 @@ class PlayerView: UIView {
}
}
}

extension AVDateRangeMetadataGroup {
func shouldShow(for item: AVPlayerItem) -> Bool {
guard let endDate = endDate, let currentDate = item.currentDate() else { return false }
return startDate <= currentDate && currentDate < endDate
}
}
9 changes: 5 additions & 4 deletions Example/HMSSDKExample/Meeting/HMSSDKInteractor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -206,20 +206,21 @@ final class HMSSDKInteractor: HMSUpdateListener {
if let audio = track as? HMSAudioTrack {
updatedMuteStatus?(audio)
}
if let videoTrack = track as? HMSVideoTrack, videoTrack.source == HMSCommonTrackSource.screen {
if let videoTrack = track as? HMSRemoteVideoTrack, videoTrack.source == HMSCommonTrackSource.screen {
if update == .trackAdded {
pipController.set(screenTrack: videoTrack)
}
else {
else if update == .trackRemoved {
pipController.remove(screenTrack: videoTrack)
}
}
}

func on(error: HMSError) {
func on(error: Error) {
guard let error = error as? HMSError else { return }
NotificationCenter.default.post(name: Constants.gotError,
object: nil,
userInfo: ["error": error.message])
userInfo: ["error": "\(error.localizedDescription)"])
}

func on(message: HMSMessage) {
Expand Down
55 changes: 47 additions & 8 deletions Example/HMSSDKExample/Meeting/MeetingViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -490,7 +490,7 @@ final class MeetingViewController: UIViewController, UIDocumentPickerDelegate {
image: UIImage(systemName: "stop.circle")) { [weak self] _ in
guard let self = self else { return }
self.interactor?.hmsSDK?.stopRTMPAndRecording { [weak self] _, error in
if let error = error {
if let error = error as? HMSError {
self?.showActionError(error, action: "Stop RTMP/Recording")
return
}
Expand All @@ -511,22 +511,29 @@ final class MeetingViewController: UIViewController, UIDocumentPickerDelegate {
image: UIImage(systemName: "stop.circle")) { [weak self] _ in
guard let self = self else { return }
self.interactor?.hmsSDK?.stopHLSStreaming { [weak self] _, error in
if let error = error {
if let error = error as? HMSError {
self?.showActionError(error, action: "Stop HLS")
return
}
self?.updateSettingsButton()
}
}
actions.append(stopHLS)

let sendMetadata = UIAction(title: "Send HLS Timed Metadata",
image: UIImage(systemName: "tray.and.arrow.up.fill")) { [weak self] _ in
guard let self = self else { return }
self.showMetadataPrompt()
}
actions.append(sendMetadata)

if interactor.canEndRoom {
let endRoomAction = UIAction(title: "End Room",
image: UIImage(systemName: "xmark.octagon.fill")) { [weak self] _ in
guard let self = self else { return }

self.interactor?.hmsSDK?.endRoom(reason: "Meeting Ended") { [weak self] _, error in
if let error = error {
if let error = error as? HMSError {
self?.showActionError(error, action: "End Room")
return
}
Expand Down Expand Up @@ -610,7 +617,7 @@ final class MeetingViewController: UIViewController, UIDocumentPickerDelegate {
}

self?.interactor.hmsSDK?.change(name: name, completion: { _, error in
if let error = error {
if let error = error as? HMSError {
self?.showActionError(error, action: "Change name")
} else {
UserDefaults.standard.set(name, forKey: Constants.defaultName)
Expand All @@ -620,6 +627,36 @@ final class MeetingViewController: UIViewController, UIDocumentPickerDelegate {

present(alertController, animated: true)
}

private func showMetadataPrompt() {
let title = "Enter metadata to send"
let action = "Send"

let alertController = UIAlertController(title: title,
message: nil,
preferredStyle: .alert)

alertController.addTextField { textField in
textField.clearButtonMode = .always
}

alertController.addAction(UIAlertAction(title: "Cancel", style: .cancel))
alertController.addAction(UIAlertAction(title: action, style: .default) { [weak self] _ in
guard let metadataPayload = alertController.textFields?[0].text, !metadataPayload.isEmpty else {
return
}

let metadata = HMSHLSTimedMetadata(payload: metadataPayload, duration: 5)

self?.interactor.hmsSDK?.sendHLSTimedMetadata([metadata], completion: { _, error in
if let error = error as? HMSError {
self?.showActionError(error, action: "Send Metadata")
}
})
})

present(alertController, animated: true)
}

private func showMutePrompt() {

Expand Down Expand Up @@ -733,6 +770,8 @@ final class MeetingViewController: UIViewController, UIDocumentPickerDelegate {

private func handle(removedFromRoom notification: HMSRemovedFromRoomNotification) {
let title = "\(notification.requestedBy?.name ?? "100ms app") removed you from this room: \(notification.reason)"

interactor.pipController.roomEnded(reason: title)

let alertController = UIAlertController(title: title,
message: nil,
Expand Down Expand Up @@ -783,7 +822,7 @@ final class MeetingViewController: UIViewController, UIDocumentPickerDelegate {
let title = "Could Not \(action)"

let alertController = UIAlertController(title: title,
message: error.message,
message: error.localizedDescription,
preferredStyle: .alert)

alertController.addAction(UIAlertAction(title: "OK", style: .cancel))
Expand Down Expand Up @@ -880,7 +919,7 @@ final class MeetingViewController: UIViewController, UIDocumentPickerDelegate {
sender.isSelected = !sender.isSelected
let meta = PeerMetadata(isHandRaised: sender.isSelected)
interactor?.hmsSDK?.change(metadataObject: meta) { [weak self] _, error in
if let error = error {
if let error = error as? HMSError {
self?.showActionError(error, action: "Raise hand")
}
}
Expand Down Expand Up @@ -932,7 +971,7 @@ extension MeetingViewController: ChangeAllRoleViewControllerDelegate {
extension MeetingViewController: RTMPSettingsViewControllerDelegate {
func rtmpSettingsController(_ rtmpSettingsController: RTMPSettingsViewController, didSelect config: HMSRTMPConfig) {
interactor?.hmsSDK?.startRTMPOrRecording(config: config) { [weak self] _, error in
if let error = error {
if let error = error as? HMSError {
self?.showActionError(error, action: "Start RTMP/Recording")
return
}
Expand All @@ -945,7 +984,7 @@ extension MeetingViewController: RTMPSettingsViewControllerDelegate {
extension MeetingViewController: HLSSettingsViewControllerDelegate {
func hlsSettingsController(_ hlsSettingsController: HLSSettingsViewController, didSelect config: HMSHLSConfig?) {
interactor?.hmsSDK?.startHLSStreaming(config: config) { [weak self] _, error in
if let error = error {
if let error = error as? HMSError {
self?.showActionError(error, action: "Start HLS Streaming")
return
}
Expand Down
6 changes: 6 additions & 0 deletions Example/HMSSDKExample/Meeting/MeetingViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,7 @@ final class MeetingViewModel: NSObject,

cell.videoView.mirror = true
cell.videoView.videoContentMode = .scaleAspectFill
cell.videoView.isZoomAndPanEnabled = false

if viewModel.peer is HMSRemotePeer {

Expand All @@ -405,6 +406,11 @@ final class MeetingViewModel: NSObject,
} else {
cell.moreButton.isHidden = false
}

// Let's enable panning and zooming in screen share view
if viewModel.videoTrack?.source == HMSCommonTrackSource.screen {
cell.videoView.isZoomAndPanEnabled = true
}
}
}

Expand Down
20 changes: 10 additions & 10 deletions Example/HMSSDKExample/Meeting/Menus/RoomStateViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,9 @@ class RoomStateViewController: FormViewController {
}
}

if let error = room.browserRecordingState.error {
if let error = room.browserRecordingState.error as? HMSError {
section <<< LabelRow() {
$0.title = "Error: \(error.message) (\(error.code))"
$0.title = "Error: \(error.localizedDescription)"
}
}
form +++ section
Expand All @@ -78,9 +78,9 @@ class RoomStateViewController: FormViewController {
$0.title = "Started at: \(startDate)"
}
}
if let error = room.serverRecordingState.error {
if let error = room.serverRecordingState.error as? HMSError {
section <<< LabelRow() {
$0.title = "Error: \(error.message) (\(error.code))"
$0.title = "Error: \(error.localizedDescription)"
}
}
form +++ section
Expand All @@ -105,9 +105,9 @@ class RoomStateViewController: FormViewController {
}
}

if let error = room.hlsRecordingState.error {
if let error = room.hlsRecordingState.error as? HMSError {
section <<< LabelRow() {
$0.title = "Error: \(error.message) (\(error.code))"
$0.title = "Error: \(error.localizedDescription)"
}
}

Expand All @@ -124,9 +124,9 @@ class RoomStateViewController: FormViewController {
$0.title = "Started at: \(startDate)"
}
}
if let error = room.rtmpStreamingState.error {
if let error = room.rtmpStreamingState.error as? HMSError {
section <<< LabelRow() {
$0.title = "Error: \(error.message) (\(error.code))"
$0.title = "Error: \(error.localizedDescription)"
}
}
form +++ section
Expand All @@ -149,9 +149,9 @@ class RoomStateViewController: FormViewController {
count += 1
}

if let error = room.rtmpStreamingState.error {
if let error = room.rtmpStreamingState.error as? HMSError {
section <<< LabelRow() {
$0.title = "Error: \(error.message) (\(error.code))"
$0.title = "Error: \(error.localizedDescription)"
}
}
form +++ section
Expand Down
Loading

0 comments on commit b794a48

Please sign in to comment.