Closed Rockjan closed 4 years ago
I don’t know if my code is right (actually the app crashed......)
NSMutableArray *codecs = [[NSMutableArray alloc] initWithCapacity:3];
[codecs addObject:[RTCUtils genRtpEncodingParameters:YES maxBitrateBps:400000 minBitrateBps:0 maxFramerate:60 numTemporalLayers:0 scaleResolutionDownBy:0]];
[codecs addObject:[RTCUtils genRtpEncodingParameters:YES maxBitrateBps:1000000 minBitrateBps:0 maxFramerate:60 numTemporalLayers:0 scaleResolutionDownBy:0]];
[codecs addObject:[RTCUtils genRtpEncodingParameters:YES maxBitrateBps:1500000 minBitrateBps:0 maxFramerate:60 numTemporalLayers:0 scaleResolutionDownBy:0]];
NSString *str = [weakSelf stringFromDict:@{@"videoGoogleStartBitrate": @(1000)}];
RTCVideoTrack *videoTrack = [capturer createVideoTrackWithPresentView:videoView];
//Crashed at this line
Producer *producer = [weakSelf.sendTransport produce:nil track:videoTrack encodings:codecs codecOptions:str];
Crash info : *** Terminating app due to uncaught exception 'RuntimeException', reason: 'error creating transceiver'
I don’t know if my code is right (actually the app crashed......)
NSMutableArray *codecs = [[NSMutableArray alloc] initWithCapacity:3]; [codecs addObject:[RTCUtils genRtpEncodingParameters:YES maxBitrateBps:400000 minBitrateBps:0 maxFramerate:60 numTemporalLayers:0 scaleResolutionDownBy:0]]; [codecs addObject:[RTCUtils genRtpEncodingParameters:YES maxBitrateBps:1000000 minBitrateBps:0 maxFramerate:60 numTemporalLayers:0 scaleResolutionDownBy:0]]; [codecs addObject:[RTCUtils genRtpEncodingParameters:YES maxBitrateBps:1500000 minBitrateBps:0 maxFramerate:60 numTemporalLayers:0 scaleResolutionDownBy:0]]; NSString *str = [weakSelf stringFromDict:@{@"videoGoogleStartBitrate": @(1000)}]; RTCVideoTrack *videoTrack = [capturer createVideoTrackWithPresentView:videoView]; //Crashed at this line Producer *producer = [weakSelf.sendTransport produce:nil track:videoTrack encodings:codecs codecOptions:str];
Crash info : *** Terminating app due to uncaught exception 'RuntimeException', reason: 'error creating transceiver'
Finally, I found the reason:
it should be: [codecs addObject:[RTCUtils genRtpEncodingParameters:YES maxBitrateBps:400000 minBitrateBps:0 maxFramerate:60 numTemporalLayers:0 scaleResolutionDownBy:4]]; [codecs addObject:[RTCUtils genRtpEncodingParameters:YES maxBitrateBps:1000000 minBitrateBps:0 maxFramerate:60 numTemporalLayers:0 scaleResolutionDownBy:2]]; [codecs addObject:[RTCUtils genRtpEncodingParameters:YES maxBitrateBps:1500000 minBitrateBps:0 maxFramerate:60 numTemporalLayers:0 scaleResolutionDownBy:1]];
Hi is Simulcast available please share example code.
Hi is Simulcast available please share example code.
Hi, just use the code below to create a producer, then simulcast will be open (maybe you should use your own parameters):
NSMutableArray *codecs = [[NSMutableArray alloc] initWithCapacity:3];
[codecs addObject:[RTCUtils genRtpEncodingParameters:YES maxBitrateBps:400000 minBitrateBps:0 maxFramerate:15 numTemporalLayers:2 scaleResolutionDownBy:3]];
[codecs addObject:[RTCUtils genRtpEncodingParameters:YES maxBitrateBps:550000 minBitrateBps:0 maxFramerate:20 numTemporalLayers:2 scaleResolutionDownBy:2]];
[codecs addObject:[RTCUtils genRtpEncodingParameters:YES maxBitrateBps:1300000 minBitrateBps:0 maxFramerate:25 numTemporalLayers:2 scaleResolutionDownBy:1]];
@try
{
RTCVideoTrack *videoTrack = [capturer createVideoTrackWithPresentView:videoView];
producer = [weakSelf.sendTransport produce:nil track:videoTrack encodings:codecs codecOptions:nil];
}
@catch (NSException * e)
{
NSLog(@" - genVideoProducerWithCapturer Exception: %@", e);
}
RTCVideoTrack *videoTrack = [capturer createVideoTrackWithPresentView:videoView];
producer = [weakSelf.sendTransport produce:nil track:videoTrack encodings:nil codecOptions:nil];
Than you very much, let me try
sorry for asking extended help, If possible please give full sample code.
sorry for asking extended help, If possible please give full sample code.
Sorry, I can't offer you my full code because they are owned by my company.
Maybe you can have a look at example code offered by ethand91 : https://github.com/ethand91/mediasoup-ios-client-sample.
Thanks bro for your quick response, I am already done with 1 to 1 it's working fine, I am facing issue only with multicast, If possible please help me how to handle multicast, I already added above code you mentioned it stoping display video.
No difference between 1v1 and 1vN, just join the same room. The code I show you is to enable simulcast, it's already supported by mediasoup. I dont know what happend to your code, maybe you can post you code to us and then we could help you.
Thanks for your response, Here it is not possible to share full code, Please give me your mail id i will send you full code below provided roomclient and mainviewcontroller code please check Below code related to roomClient
import Foundation import SwiftyJSON
protocol SendTransportHandlerDelegate: class { func sendSocketConnectionStatus(connectionStatus: String) }
public enum RoomError : Error { case DEVICE_NOT_LOADED case SEND_TRANSPORT_NOT_CREATED case RECV_TRANSPORT_NOT_CREATED case DEVICE_CANNOT_PRODUCE_VIDEO case DEVICE_CANNOT_PRODUCE_AUDIO case PRODUCER_NOT_FOUND case CONSUMER_NOT_FOUND }
final internal class RoomClient : NSObject {
private static let STATS_INTERVAL_MS: NSInteger = 3000
private let socket: EchoSocket
private let roomId: String
private let mediaCapturer: MediaCapturer
private var producers: [String : Producer]
private var consumers: [String : Consumer]
private var consumersInfo: [JSON]
private let device: MediasoupDevice
private var joined: Bool
private var sendTransport: SendTransport?
private var recvTransport: RecvTransport?
private var sendTransportHandler: SendTransportHandler?
private var recvTransportHandler: RecvTransportHandler?
private var producerHandler: ProducerHandler?
private var consumerHandler: ConsumerHandler?
private var roomListener: RoomListener?
public init(socket: EchoSocket, device: MediasoupDevice, roomId: String, roomListener: RoomListener) {
self.socket = socket
self.device = device
self.roomId = roomId
self.roomListener = roomListener
self.mediaCapturer = MediaCapturer.shared
self.producers = [String : Producer]()
self.consumers = [String : Consumer]()
self.consumersInfo = [JSON]()
self.joined = false
super.init()
}
func join() throws {
// Check if the device is loaded
if !self.device.isLoaded() {
throw RoomError.DEVICE_NOT_LOADED
}
// if the user is already joined do nothing
if self.joined {
return
}
_ = Request.shared.sendLoginRoomRequest(socket: self.socket, roomId: self.roomId, deviceRtpCapabilities: self.device.getRtpCapabilities())
self.joined = true
print("join() join success")
}
func createSendTransport() {
// Do nothing if send transport is already created
if (self.sendTransport != nil) {
print("createSendTransport() send transport is already created...")
return
}
self.createWebRtcTransport(direction: "send")
print("createSendTransport() send transport created")
}
func createRecvTransport() {
// Do nothing if recv transport is already created
if (self.recvTransport != nil) {
print("createRecvTransport() recv transport is already created...")
return
}
self.createWebRtcTransport(direction: "recv")
print("createRecvTransport() recv transport created")
}
func switchCamera() {
self.mediaCapturer.switchCamera()
}
func produceVideo(videoView: RTCEAGLVideoView) throws -> RTCVideoTrack? {
if self.sendTransport == nil {
print("trasnport nil")
throw RoomError.SEND_TRANSPORT_NOT_CREATED
}
if !self.device.canProduce("video") {
print("cannot produce")
throw RoomError.DEVICE_CANNOT_PRODUCE_VIDEO
}
let codecOptions: JSON = [
"videoGoogleStartBitrate": 1000
]
var videoTrack: RTCVideoTrack
var producer: Producer
do {
// Converted to Swift 5.3 by Swiftify v5.3.29902 - https://swiftify.com/
#if ENABLE_SIMULCAST
var encodings = [AnyHashable](repeating: 0, count: 3)
encodings.append(RTCUtils.genRtpEncodingParameters(true, maxBitrateBps: 400000, minBitrateBps: 0, maxFramerate: 15, numTemporalLayers: 2, scaleResolutionDownBy: 3))
encodings.append(RTCUtils.genRtpEncodingParameters(true, maxBitrateBps: 550000, minBitrateBps: 0, maxFramerate: 20, numTemporalLayers: 2, scaleResolutionDownBy: 2))
encodings.append(RTCUtils.genRtpEncodingParameters(true, maxBitrateBps: 1300000, minBitrateBps: 0, maxFramerate: 25, numTemporalLayers: 2, scaleResolutionDownBy: 1))
do {
videoTrack = try mediaCapturer.createVideoTrack(videoView: videoView)
producer = sendTransport?.produce(nil, track: videoTrack, encodings: encodings, codecOptions: nil)
} catch {
print(" - genVideoProducerWithCapturer Exception")
}
#else
videoTrack = try mediaCapturer.createVideoTrack(videoView: videoView)
producer = (sendTransport?.produce(nil, track: videoTrack, encodings: nil, codecOptions: nil))!
//producer = self.createProducer(track: videoTrack, codecOptions: codecOptions.description, encodings: nil)
#endif
}
return videoTrack
}
func produceAudio() throws {
if self.sendTransport == nil {
throw RoomError.SEND_TRANSPORT_NOT_CREATED
}
if !self.device.canProduce("audio") {
throw RoomError.DEVICE_CANNOT_PRODUCE_AUDIO
}
let audioTrack: RTCAudioTrack = self.mediaCapturer.createAudioTrack()
self.createProducer(track: audioTrack, codecOptions: nil, encodings: nil)
}
func pauseLocalVideo() throws {
print("pauseLocalVideo()")
let producer: Producer = try self.getProducerByKind(kind: "video")
print("producervideo:\(producer)")
producer.pause()
}
func resumeLocalVideo() throws {
print("resumeLocalVideo()")
let producer: Producer = try self.getProducerByKind(kind: "video")
print("resumeproducervideo:\(producer)")
producer.resume()
//Request.shared.sendResumeProducerRequest(socket: self.socket, roomId: self.roomId, producerId: producer.getId())
}
func pauseLocalAudio() throws {
print("pauseLocalAudio()")
let producer: Producer = try self.getProducerByKind(kind: "audio")
Request.shared.sendPauseProducerRequest(socket: self.socket, roomId: self.roomId, producerId: producer.getId())
}
func resumeLocalAudio() throws {
print("resumeLocalAudio()")
let producer: Producer = try self.getProducerByKind(kind: "audio")
Request.shared.sendResumeProducerRequest(socket: self.socket, roomId: self.roomId, producerId: producer.getId())
}
var countVideo = 0
var countAudio = 0
func consumeTrack(consumerInfo: JSON) {
if (self.recvTransport == nil) {
// User has not yet created a transport for receiving so temporarily store it
// and play it when the recv transport is created
self.consumersInfo.append(consumerInfo)
return
}
let kind: String = consumerInfo["kind"].stringValue
// if already consuming type of track remove it, TODO support multiple remotes?
for consumer in self.consumers.values {
if consumer.getKind() == kind {
print("consumeTrack() removing consumer kind=" + kind)
self.consumers.removeValue(forKey: consumer.getId())
}
}
var producerId = ""
print("ppp:\(consumerInfo)")
let id: String = consumerInfo["id"].stringValue
producerId = consumerInfo["producerId"].stringValue
if producerId == "" {
producerId = consumerInfo["data"]["id"].stringValue
}
print("producerIddd:\(producerId)")
let rtpParameters: JSON = consumerInfo["rtpParameters"]
print("consumeTrack() rtpParameters " + rtpParameters.description)
self.consumerHandler = ConsumerHandler.init()
self.consumerHandler!.delegate = self.consumerHandler
let kindConsumer: Consumer = self.recvTransport!.consume(self.consumerHandler!.delegate!, id: id, producerId: producerId, kind: kind, rtpParameters: rtpParameters.description)
self.consumers[kindConsumer.getId()] = kindConsumer
print("consumeTrack() consuming id =" + kindConsumer.getId())
let peers = consumerInfo["peers"]
self.roomListener?.onNewConsumer(consumer: kindConsumer)
}
func consumeTrack1(consumerInfo: JSON) {
if (self.recvTransport == nil) {
// User has not yet created a transport for receiving so temporarily store it
// and play it when the recv transport is created
self.consumersInfo.append(consumerInfo)
return
}
let kind: String = consumerInfo["kind"].stringValue
// if already consuming type of track remove it, TODO support multiple remotes?
for consumer in self.consumers.values {
if consumer.getKind() == kind {
print("consumeTrack() removing consumer kind=" + kind)
self.consumers.removeValue(forKey: consumer.getId())
}
}
var producerId = ""
print("ppp:\(consumerInfo)")
let id: String = consumerInfo["id"].stringValue
producerId = consumerInfo["producerId"].stringValue
if producerId == "" {
producerId = consumerInfo["data"]["id"].stringValue
}
print("producerIddd:\(producerId)")
/* if (countVideo > 0 && countAudio > 0) {
return
} else if (countVideo > 0 && countAudio == 0) {
if (kind == "video") {
return
}
} else if (countAudio > 0 && countVideo == 0) {
if (kind == "audio") {
return
}
}
if (kind == "video") {
countVideo = 1
}
if (kind == "audio") {
countAudio = 1
}*/
let rtpParameters: JSON = consumerInfo["rtpParameters"]
print("consumeTrack() rtpParameters " + rtpParameters.description)
self.consumerHandler = ConsumerHandler.init()
self.consumerHandler!.delegate = self.consumerHandler
let kindConsumer: Consumer = self.recvTransport!.consume(self.consumerHandler!.delegate!, id: id, producerId: producerId, kind: kind, rtpParameters: rtpParameters.description)
self.consumers[kindConsumer.getId()] = kindConsumer
print("consumeTrack() consuming id =" + kindConsumer.getId())
self.roomListener?.onNewConsumer1(consumer: kindConsumer)
}
func consumeCurrentLayers(consumerInfo: JSON) throws {
self.consumerHandler = ConsumerHandler.init()
self.consumerHandler!.delegate = self.consumerHandler
let consumerId = consumerInfo["data"]["consumerId"].stringValue
let consumer: Consumer = try self.getConsumerByKind(kind: "video")
self.consumers[consumerId] = consumer
print("consumeTrack() consuming id1 =" + consumer.getId())
self.roomListener?.onNewConsumer1(consumer: consumer)
}
func pauseRemoteVideo() throws {
let consumer: Consumer = try self.getConsumerByKind(kind: "video")
consumer.pause()
//Request.shared.sendPauseConsumerRequest(socket: self.socket, roomId: self.roomId, consumerId: consumer.getId())
}
func removeRemoteVideo() throws {
let consumer: Consumer = try self.getConsumerByKind(kind: "video")
//consumer.remove()
//Request.shared.sendPauseConsumerRequest(socket: self.socket, roomId: self.roomId, consumerId: consumer.getId())
}
func addRemoteVideo(json: JSON) throws {
let consumer: Consumer = try self.getConsumerByKind(kind: "video")
let peerId = json["peerId"].stringValue
self.consumers[peerId] = consumer
self.roomListener?.onNewConsumer1(consumer: consumer)
print("peerId:\(peerId)")
//Request.shared.sendPauseConsumerRequest(socket: self.socket, roomId: self.roomId, consumerId: consumer.getId())
}
func resumeRemoteVideo() throws {
let consumer: Consumer = try self.getConsumerByKind(kind: "video")
consumer.resume()
print("consumerId1:\(consumer.getId())")
Request.shared.sendResumeConsumerRequest(socket: self.socket, roomId: self.roomId, consumerId: consumer.getId())
}
func resumeRemoteVideo1() throws {
let consumer: Consumer = try self.getConsumerByKind(kind: "video")
consumer.resume()
print("consumerId2:\(consumer.getId())")
Request.shared.sendResumeConsumerRequest(socket: self.socket, roomId: self.roomId, consumerId: consumer.getId())
}
func pauseRemoteAudio() throws {
let consumer: Consumer = try self.getConsumerByKind(kind: "audio")
Request.shared.sendPauseConsumerRequest(socket: self.socket, roomId: self.roomId, consumerId: consumer.getId())
}
func resumeRemoteAudio() throws {
let consumer: Consumer = try self.getConsumerByKind(kind: "audio")
Request.shared.sendResumeConsumerRequest(socket: self.socket, roomId: self.roomId, consumerId: consumer.getId())
}
private func createWebRtcTransport(direction: String) {
let response: JSON = Request.shared.sendCreateWebRtcTransportRequest(socket: self.socket, roomId: self.roomId, direction: direction)
print("createWebRtcTransport() response = " + response.description)
let webRtcTransportData: JSON = response["data"]
let id: String = webRtcTransportData["id"].stringValue
let iceParameters: JSON = webRtcTransportData["iceParameters"]
let iceCandidatesArray: JSON = webRtcTransportData["iceCandidates"]
let dtlsParameters: JSON = webRtcTransportData["dtlsParameters"]
switch direction {
case "send":
self.sendTransportHandler = SendTransportHandler.init(parent: self)
self.sendTransportHandler!.delegate = self.sendTransportHandler!
self.sendTransport = self.device.createSendTransport(self.sendTransportHandler!.delegate!, id: id, iceParameters: iceParameters.description, iceCandidates: iceCandidatesArray.description, dtlsParameters: dtlsParameters.description)
break
case "recv":
self.recvTransportHandler = RecvTransportHandler.init(parent: self)
self.recvTransportHandler!.delegate = self.recvTransportHandler!
self.recvTransport = self.device.createRecvTransport(self.recvTransportHandler!.delegate!, id: id, iceParameters: iceParameters.description, iceCandidates: iceCandidatesArray.description, dtlsParameters: dtlsParameters.description)
// Play consumers that have been stored
for consumerInfo in self.consumersInfo {
print("consumerInfofina:\(consumerInfo)")
self.consumeTrack(consumerInfo: consumerInfo)
}
break
default:
print("createWebRtcTransport() invalid direction " + direction)
}
}
private func createProducer(track: RTCMediaStreamTrack, codecOptions: String?, encodings: Array<RTCRtpEncodingParameters>?) {
self.producerHandler = ProducerHandler.init()
self.producerHandler!.delegate = self.producerHandler!
let kindProducer: Producer = self.sendTransport!.produce(self.producerHandler!.delegate!, track: track, encodings: encodings, codecOptions: codecOptions)
self.producers[kindProducer.getId()] = kindProducer
print("createProducer() created id =" + kindProducer.getId() + " kind =" + kindProducer.getKind())
}
private func handleLocalTransportConnectEvent(transport: Transport, dtlsParameters: String) {
print("handleLocalTransportConnectEvent() id =" + transport.getId())
Request.shared.sendConnectWebRtcTransportRequest(socket: self.socket, roomId: self.roomId, transportId: transport.getId(), dtlsParameters: dtlsParameters)
}
private func handleLocalTransportProduceEvent(transport: Transport, kind: String, rtpParameters: String, appData: String) -> String {
print("handleLocalTransportProduceEvent() id =" + transport.getId() + " kind = " + kind)
var producerId: String = ""
let transportProduceResponse: JSON = Request.shared.sendProduceWebRtcTransportRequest(socket: self.socket, roomId: self.roomId, transportId: transport.getId(), kind: kind, rtpParameters: rtpParameters)
print("transportProduceResponse:\(transportProduceResponse)--data:\(transportProduceResponse["producerId"].stringValue)--data1:\(transportProduceResponse["data"]["id"].stringValue)")
producerId = transportProduceResponse["producerId"].stringValue
if producerId == "" {
producerId = transportProduceResponse["data"]["id"].stringValue
}
print("producerId:\(producerId)")
return producerId
}
private func getProducerByKind(kind: String) throws -> Producer {
print("kind:\(producers.values)")
for producer in self.producers.values {
print("kindproducer:\(producer.getKind())--\(kind)")
if producer.getKind() == kind {
return producer
}
}
throw RoomError.PRODUCER_NOT_FOUND
}
private func getConsumerByKind(kind: String) throws -> Consumer {
for consumer in self.consumers.values {
if consumer.getKind() == kind {
return consumer
}
}
throw RoomError.CONSUMER_NOT_FOUND
}
// Class to handle send transport listener events
private class SendTransportHandler : NSObject, SendTransportListener {
fileprivate weak var delegate: SendTransportListener?
private var parent: RoomClient
weak var socketDelegate: SendTransportHandlerDelegate?
init(parent: RoomClient) {
self.parent = parent
}
func onConnect(_ transport: Transport!, dtlsParameters: String!) {
print("SendTransport::onConnect dtlsParameters = " + dtlsParameters)
self.parent.handleLocalTransportConnectEvent(transport: transport, dtlsParameters: dtlsParameters)
}
func onConnectionStateChange(_ transport: Transport!, connectionState: String!) {
print("SendTransport::onConnectionStateChange connectionState = " + connectionState)
if connectionState == "disconnected" {
socketDelegate?.sendSocketConnectionStatus(connectionStatus: connectionState)
}
}
func onProduce(_ transport: Transport!, kind: String!, rtpParameters: String!, appData: String!, callback: ((String?) -> Void)!) {
let producerId = self.parent.handleLocalTransportProduceEvent(transport: transport, kind: kind, rtpParameters: rtpParameters, appData: appData)
callback(producerId)
}
}
// Class to handle recv transport listener events
private class RecvTransportHandler : NSObject, RecvTransportListener {
fileprivate weak var delegate: RecvTransportListener?
private var parent: RoomClient
init(parent: RoomClient) {
self.parent = parent
}
func onConnect(_ transport: Transport!, dtlsParameters: String!) {
print("RecvTransport::onConnect")
self.parent.handleLocalTransportConnectEvent(transport: transport, dtlsParameters: dtlsParameters)
}
func onConnectionStateChange(_ transport: Transport!, connectionState: String!) {
print("RecvTransport::onConnectionStateChange newState = " + connectionState)
}
}
// Class to handle producer listener events
private class ProducerHandler : NSObject, ProducerListener {
fileprivate weak var delegate: ProducerListener?
func onTransportClose(_ producer: Producer!) {
print("Producer::onTransportClose")
}
}
// Class to handle consumer listener events
private class ConsumerHandler : NSObject, ConsumerListener {
fileprivate weak var delegate: ConsumerListener?
func onTransportClose(_ consumer: Consumer!) {
print("Consumer::onTransportClose")
}
}
}
videoVC controller code
extension VideoCallVC : MessageObserver { func on(event: String, data: JSON?) {
switch event {
case ActionEvent.OPEN:
print("socket connected")
self.handleWebSocketConnected()
break
case ActionEvent.NEW_USER:
print("NEW_USER id =" + data!["userId"]["userId"].stringValue)
break
case ActionEvent.NEW_DATA_CONSUMER:
print("NEW_CONSUMER1 data=" + data!.description)
// self.handleNewConsumerEvent(consumerInfo: data!["data"])
break
case ActionEvent.NEW_CONSUMER:
// isRemoteVideo = true
print("NEW_CONSUMER data=" + data!.description)
// self.handleNewConsumerEvent(consumerInfo: data!["data"])
isRemoteVideo = true
self.handleNewConsumerEvent(consumerInfo: data!["data"])
break
case "newPeer":
print("NEW_Peer data=" + data!.description)
addRemoteVideo(json: data!["data"])
// pauseLocalStream()
break
case "peerClosed":
print("NEW_Peer data=" + data!.description)
let peerId = data!["id"]
// pauseLocalStream()
break
case ActionEvent.CLOSED_CONSUMER:
print("CLOSED_CONSUMER data=" + data!.description)
// isRemoteVideoPaused = true
pauseRemoteVideo()
/*DispatchQueue.main.async {
self.viewRemoteCamera.isHidden = true
self.viewRemoteCamera.backgroundColor = .black
self.labelWaitingParticipants.isHidden = false
self.labelWaitingParticipants.text = "Remote video paused..."
}*/
case ActionEvent.CONSUMER_LAYER_CHANGED:
print("CONSUMER_LAYER_CHANGED data=" + data!.description)
// if data!["data"]["spatialLayer"] > 1 { // addRemoteVideo(json: data!["data"]) // }
// print(data!["data"]["spatialLayer"]) // if data!["data"]["spatialLayer"] >= 1 { // let consumer = Consumer() // let videoTrack = RTCVideoTrack.self as! RTCVideoTrack // videoTrack.isEnabled = true // videoTrack.add(self.videoRemoteCamera1) // }
// do { // try self.handleVideoConsumerEvent(consumerInfo: data!["data"]) // // } // catch { // print("failed to create video track") // }
case ActionEvent.PAUSE_CONSUMER:
print("PAUSE_CONSUMER data=" + data!.description)
case ActionEvent.PAUSE_PRODUCER:
print("PAUSE_PRODUCER data=" + data!.description)
case ActionEvent.RESUME_PRODUCER:
print("RESUME_PRODUCER data=" + data!.description)
case ActionEvent.RESUME_CONSUMER:
print("RESUME_CONSUMER data=" + data!.description)
DispatchQueue.main.async {
// self.viewRemoteCamera.isHidden = false
self.resumeRemoteVideo()
}
case "activeSpeaker":
break
default:
print("Unknown event " + event)
}
}
private func handleNewConsumerEvent(consumerInfo: JSON) {
print("handleNewConsumerEvent info = " + consumerInfo.description)
// Start consuming
self.client!.consumeTrack(consumerInfo: consumerInfo)
}
private func handleVideoConsumerEvent(consumerInfo: JSON) throws {
print("handleVideoConsumerEvent info = " + consumerInfo.description)
// Start consuming
try! self.client!.consumeTrack1(consumerInfo: consumerInfo)
}
}
// Extension for RoomListener extension VideoCallVC : RoomListener { func onNewConsumer1(consumer: Consumer) { print("RoomListener::onNewConsumer kind1=" + consumer.getKind()) print(consumer.getTrack())
if consumer.getKind() == "video" {
let videoTrack: RTCVideoTrack = consumer.getTrack() as! RTCVideoTrack
videoTrack.isEnabled = true
if isRemoteVideo == true {
/* DispatchQueue.main.async {
videoTrack.remove(self.imageViewOwnCamera)
self.imageViewOwnCamera.isHidden = false
self.labelWaitingParticipants.isHidden = true
_ = try! self.client!.produceVideo(videoView: self.imageViewOwnCamera)
}*/
}
videoTrack.add(self.videoRemoteCamera1)
}
do {
consumer.getKind() == "video"
? try self.client!.resumeRemoteVideo1()
: try self.client!.resumeRemoteAudio()
} catch {
print("onNewConsumer() failed to resume remote track")
}
}
func onNewConsumer(consumer: Consumer) {
print("RoomListener::onNewConsumer kind=" + consumer.getKind())
print(consumer.getTrack())
if consumer.getKind() == "video" {
let videoTrack: RTCVideoTrack = consumer.getTrack() as! RTCVideoTrack
videoTrack.isEnabled = true
if isRemoteVideo == true {
/* DispatchQueue.main.async {
videoTrack.remove(self.imageViewOwnCamera)
self.imageViewOwnCamera.isHidden = false
self.labelWaitingParticipants.isHidden = true
_ = try! self.client!.produceVideo(videoView: self.imageViewOwnCamera)
}*/
}
print("consId:\(consumer.getId())")
videoTrack.add(self.viewRemoteCamera)
}
do {
consumer.getKind() == "video"
? try self.client!.resumeRemoteVideo()
: try self.client!.resumeRemoteAudio()
} catch {
print("onNewConsumer() failed to resume remote track")
}
}
}
I am taking from this https://github.com/ethand91/mediasoup-ios-client-sample for new peer added case "newPeer": isRemoteVideo = true self.handleNewConsumerEvent(consumerInfo: data!["data"])
break
and added for video added like below
extension VideoCallVC : RoomListener {
func onNewConsumer1(consumer: Consumer) {
print("RoomListener::onNewConsumer kind1=" + consumer.getKind())
print(consumer.getTrack())
if consumer.getKind() == "video" {
let videoTrack: RTCVideoTrack = consumer.getTrack() as! RTCVideoTrack
videoTrack.isEnabled = true
videoTrack.add(self.videoRemoteCamera1)
}
do {
consumer.getKind() == "video"
? try self.client!.resumeRemoteVideo1()
: try self.client!.resumeRemoteAudio()
} catch {
print("onNewConsumer() failed to resume remote track")
}
}
func onNewConsumer(consumer: Consumer) {
print("RoomListener::onNewConsumer kind=" + consumer.getKind())
print(consumer.getTrack())
if consumer.getKind() == "video" {
let videoTrack: RTCVideoTrack = consumer.getTrack() as! RTCVideoTrack
videoTrack.isEnabled = true
print("consId:\(consumer.getId())")
videoTrack.add(self.viewRemoteCamera)
}
do {
consumer.getKind() == "video"
? try self.client!.resumeRemoteVideo()
: try self.client!.resumeRemoteAudio()
} catch {
print("onNewConsumer() failed to resume remote track")
}
}
}
for remotevideo1 videoRemoteCamera and remotevideo2 videoRemoteCamera1
any updates bro
Please tell me my mistake bro for simulcast, thanks in advance
Hi, I don't know if there has a method like "[producer setSimulcastEnable:YES]" ?
If no, how can we implement Simulcast?
I really need a demo :)
Thanks.