private void AddTracks() { foreach (var track in videoStream.GetTracks()) { pc1Senders.Add(_pc1.AddTrack(track, videoStream)); } if (!videoUpdateStarted) { StartCoroutine(WebRTC.Update()); videoUpdateStarted = true; } RTCRtpCodecCapability[] codecs = null; if (codecSelector.value == 0) { codecs = RTCRtpSender.GetCapabilities(TrackKind.Video).codecs; } else { RTCRtpCodecCapability preferredCodec = availableCodecs[codecSelector.value - 1]; codecs = new[] { preferredCodec }; } RTCRtpTransceiver transceiver = _pc1.GetTransceivers().First(); RTCErrorType error = transceiver.SetCodecPreferences(codecs); if (error != RTCErrorType.None) { Debug.LogErrorFormat("RTCRtpTransceiver.SetCodecPreferences failed. {0}", error); } }
public static IList <RTCRtpCodecCapability> GetCodecs(string kind) { var caps = RTCRtpSender.GetCapabilities(kind == "audio" ? MediaStreamTrackKind.Audio : MediaStreamTrackKind.Video); var results = new List <RTCRtpCodecCapability>(caps.Codecs); return(results); }
public static IList <RTCRtpCodecCapability> GetCodecs(string kind) { var caps = RTCRtpSender.GetCapabilities(kind); var results = new List <RTCRtpCodecCapability>(caps.Codecs); return(results); }
public void TransceiverSetAudioCodecPreferences() { var peer = new RTCPeerConnection(); var capabilities = RTCRtpSender.GetCapabilities(TrackKind.Audio); var transceiver = peer.AddTransceiver(TrackKind.Audio); var error = transceiver.SetCodecPreferences(capabilities.codecs); Assert.AreEqual(RTCErrorType.None, error); }
public Task <IList <ICodec> > GetCodecsAsync(MediaKind kind) { IList <ICodec> videoCodecsList = new List <ICodec>(); IList <ICodec> audioCodecsList = new List <ICodec>(); if (kind == MediaKind.AudioCodec) { return(Task.Run(() => { RTCRtpCapabilities audioCapabilities = RTCRtpSender.GetCapabilities(new WebRtcFactory(new WebRtcFactoryConfiguration()), "audio"); IReadOnlyList <RTCRtpCodecCapability> audioCodecs = audioCapabilities.Codecs; foreach (var item in audioCodecs) { string payload = item.PreferredPayloadType.ToString(); Codec audioCodec = new Codec(); audioCodec.SetMediaKind(MediaKind.AudioCodec); audioCodec.SetId(payload); audioCodec.SetDisplayName(item.Name + " " + payload); audioCodec.SetRate((int)item.ClockRate); audioCodecsList.Add(audioCodec); } return audioCodecsList; })); } if (kind == MediaKind.VideoCodec) { return(Task.Run(() => { RTCRtpCapabilities videoCapabilities = RTCRtpSender.GetCapabilities(new WebRtcFactory(new WebRtcFactoryConfiguration()), "video"); IReadOnlyList <RTCRtpCodecCapability> videoCodecs = videoCapabilities.Codecs; foreach (var item in videoCodecs) { string payload = item.PreferredPayloadType.ToString(); Codec videoCodec = new Codec(); videoCodec.SetMediaKind(MediaKind.VideoCodec); videoCodec.SetId(payload); videoCodec.SetDisplayName(item.Name + " " + payload); videoCodec.SetRate((int)item.ClockRate); videoCodecsList.Add(videoCodec); } return videoCodecsList; })); } else { return(null); } }
private void OnStart() { var capabilities = RTCRtpSender.GetCapabilities(TrackKind.Video); availableCodecs = capabilities.codecs.Where(codec => !excludeCodecMimeType.Contains(codec.mimeType)).ToArray(); var list = availableCodecs .Select(codec => new Dropdown.OptionData { text = codec.mimeType + " " + codec.sdpFmtpLine }) .ToList(); codecSelector.options.AddRange(list); codecSelector.interactable = true; startButton.interactable = false; }
static bool CheckVideoCodecCapabilities() { var capabilitiesSender = RTCRtpSender.GetCapabilities(TrackKind.Video); if (!capabilitiesSender.codecs.Any()) { return(false); } var capabilitiesReceiver = RTCRtpReceiver.GetCapabilities(TrackKind.Video); if (!capabilitiesReceiver.codecs.Any()) { return(false); } return(true); }
public static bool CheckVideoSendRecvCodecSupport(EncoderType encoderType) { WebRTC.Initialize(encoderType); var capabilitiesSenderCodec = RTCRtpSender.GetCapabilities(TrackKind.Video) .codecs .Select(x => x.mimeType) .Except(excludeCodecMimeType); var capabilitiesReceiverCodec = RTCRtpReceiver.GetCapabilities(TrackKind.Video) .codecs .Select(x => x.mimeType) .Except(excludeCodecMimeType); var isSupported = capabilitiesSenderCodec.Any(x => capabilitiesReceiverCodec.Contains(x)); WebRTC.Dispose(); return(isSupported); }
public void SenderGetAudioCapabilities() { RTCRtpCapabilities capabilities = RTCRtpSender.GetCapabilities(TrackKind.Audio); Assert.NotNull(capabilities); Assert.NotNull(capabilities.codecs); Assert.IsNotEmpty(capabilities.codecs); Assert.NotNull(capabilities.headerExtensions); Assert.IsNotEmpty(capabilities.headerExtensions); foreach (var codec in capabilities.codecs) { Assert.NotNull(codec); Assert.IsNotEmpty(codec.mimeType); } foreach (var extensions in capabilities.headerExtensions) { Assert.NotNull(extensions); Assert.IsNotEmpty(extensions.uri); } }
public static bool CheckVideoSendRecvCodecSupport(EncoderType encoderType) { // hardware encoder is not supported if (encoderType == EncoderType.Hardware && !NativeMethods.GetHardwareEncoderSupport()) { return(false); } WebRTC.Initialize(encoderType); var capabilitiesSenderCodec = RTCRtpSender.GetCapabilities(TrackKind.Video) .codecs .Select(x => x.mimeType) .Except(excludeCodecMimeType); var capabilitiesReceiverCodec = RTCRtpReceiver.GetCapabilities(TrackKind.Video) .codecs .Select(x => x.mimeType) .Except(excludeCodecMimeType); var isSupported = capabilitiesSenderCodec.Any(x => capabilitiesReceiverCodec.Contains(x)); WebRTC.Dispose(); return(isSupported); }
/// <summary> /// Creates a peer connection. /// </summary> /// <returns>True if connection to a peer is successfully created.</returns> private async Task <bool> CreatePeerConnection(CancellationToken cancelationToken) { Debug.Assert(_peerConnection == null); if (cancelationToken.IsCancellationRequested) { return(false); } var config = new RTCConfiguration() { BundlePolicy = RTCBundlePolicy.Balanced, #if ORTCLIB SignalingMode = _signalingMode, GatherOptions = new RTCIceGatherOptions() { IceServers = new List <RTCIceServer>(_iceServers), } #else IceTransportPolicy = RTCIceTransportPolicy.All, IceServers = _iceServers #endif }; Debug.WriteLine("Conductor: Creating peer connection."); _peerConnection = new RTCPeerConnection(config); if (_peerConnection == null) { throw new NullReferenceException("Peer connection is not created."); } #if !ORTCLIB _peerConnection.EtwStatsEnabled = _etwStatsEnabled; _peerConnection.ConnectionHealthStatsEnabled = _peerConnectionStatsEnabled; #endif if (cancelationToken.IsCancellationRequested) { return(false); } #if ORTCLIB OrtcStatsManager.Instance.Initialize(_peerConnection); #endif OnPeerConnectionCreated?.Invoke(); _peerConnection.OnIceCandidate += PeerConnection_OnIceCandidate; #if ORTCLIB _peerConnection.OnTrack += PeerConnection_OnAddTrack; _peerConnection.OnTrackGone += PeerConnection_OnRemoveTrack; _peerConnection.OnIceConnectionStateChange += () => { Debug.WriteLine("Conductor: Ice connection state change, state=" + (null != _peerConnection ? _peerConnection.IceConnectionState.ToString() : "closed")); }; #else _peerConnection.OnAddStream += PeerConnection_OnAddStream; _peerConnection.OnRemoveStream += PeerConnection_OnRemoveStream; _peerConnection.OnConnectionHealthStats += PeerConnection_OnConnectionHealthStats; #endif Debug.WriteLine("Conductor: Getting user media."); RTCMediaStreamConstraints mediaStreamConstraints = new RTCMediaStreamConstraints { // Always include audio/video enabled in the media stream, // so it will be possible to enable/disable audio/video if // the call was initiated without microphone/camera audioEnabled = true, videoEnabled = true }; if (cancelationToken.IsCancellationRequested) { return(false); } #if ORTCLIB var tracks = await _media.GetUserMedia(mediaStreamConstraints); if (tracks != null) { RTCRtpCapabilities audioCapabilities = RTCRtpSender.GetCapabilities("audio"); RTCRtpCapabilities videoCapabilities = RTCRtpSender.GetCapabilities("video"); _mediaStream = new MediaStream(tracks); Debug.WriteLine("Conductor: Adding local media stream."); IList <MediaStream> mediaStreamList = new List <MediaStream>(); mediaStreamList.Add(_mediaStream); foreach (var mediaStreamTrack in tracks) { //Create stream track configuration based on capabilities RTCMediaStreamTrackConfiguration configuration = null; if (mediaStreamTrack.Kind == MediaStreamTrackKind.Audio && audioCapabilities != null) { configuration = await Helper.GetTrackConfigurationForCapabilities(audioCapabilities, AudioCodec); } else if (mediaStreamTrack.Kind == MediaStreamTrackKind.Video && videoCapabilities != null) { configuration = await Helper.GetTrackConfigurationForCapabilities(videoCapabilities, VideoCodec); } if (configuration != null) { _peerConnection.AddTrack(mediaStreamTrack, mediaStreamList, configuration); } } } #else _mediaStream = await _media.GetUserMedia(mediaStreamConstraints); #endif if (cancelationToken.IsCancellationRequested) { return(false); } #if !ORTCLIB Debug.WriteLine("Conductor: Adding local media stream."); _peerConnection.AddStream(_mediaStream); #endif OnAddLocalStream?.Invoke(new MediaStreamEvent() { Stream = _mediaStream }); if (cancelationToken.IsCancellationRequested) { return(false); } return(true); }
void Start() { var capabilities = RTCRtpSender.GetCapabilities(TrackKind.Video); availableCodecs = capabilities.codecs .Where(codec => !excludeCodecMimeType.Contains(codec.mimeType)) .ToList(); var list = availableCodecs .Select(codec => new Dropdown.OptionData { text = codec.mimeType + " " + codec.sdpFmtpLine }) .ToList(); codecSelector.options.AddRange(list); var previewCodec = WebRTCSettings.UseVideoCodec; codecSelector.value = previewCodec == null ? 0 : availableCodecs.FindIndex(x => x.mimeType == previewCodec.mimeType && x.sdpFmtpLine == previewCodec.sdpFmtpLine) + 1; codecSelector.onValueChanged.AddListener(OnChangeCodecSelect); var optionList = streamSizeList.Select(size => new Dropdown.OptionData($" {size.x} x {size.y} ")).ToList(); optionList.Add(new Dropdown.OptionData(" Custom ")); streamSizeSelector.options = optionList; var existInList = streamSizeList.Contains(WebRTCSettings.StreamSize); if (existInList) { streamSizeSelector.value = streamSizeList.IndexOf(WebRTCSettings.StreamSize); } else { streamSizeSelector.value = optionList.Count - 1; textureWidthInput.text = WebRTCSettings.StreamSize.x.ToString(); textureHeightInput.text = WebRTCSettings.StreamSize.y.ToString(); textureWidthInput.interactable = true; textureHeightInput.interactable = true; } streamSizeSelector.onValueChanged.AddListener(OnChangeStreamSizeSelect); textureWidthInput.onValueChanged.AddListener(OnChangeTextureWidthInput); textureHeightInput.onValueChanged.AddListener(OnChangeTextureHeightInput); toggleLimitTextureSize.isOn = WebRTCSettings.LimitTextureSize; toggleLimitTextureSize.onValueChanged.AddListener(OnChangeLimitTextureSize); buttonPeerConnection.onClick.AddListener(OnPressedPeerConnectionButton); buttonDataChannel.onClick.AddListener(OnPressedDataChannelButton); buttonMediaStream.onClick.AddListener(OnPressedMediaStreamButton); buttonAudio.onClick.AddListener(OnPressedAudioButton); buttonMultiPeers.onClick.AddListener(OnPressedMultiPeersButton); buttonMultiAudioRecv.onClick.AddListener(OnPressedMultiAudioRecvButton); buttonMultiVideoRecv.onClick.AddListener(OnPressedMultiVideoRecvButton); buttonMungeSDP.onClick.AddListener(OnPressedMungeSDPButton); buttonStats.onClick.AddListener(OnPressedStatsButton); buttonChangeCodecs.onClick.AddListener(OnPressedChangeCodecsButton); buttonTrickleIce.onClick.AddListener(OnPressedTrickleIceButton); buttonVideoReceive.onClick.AddListener(OnPressedVideoReceiveButton); buttonBandwidth.onClick.AddListener(OnPressedBandwidthButton); buttonPerfectNegotiation.onClick.AddListener(OnPressedPerfectNegotiationButton); buttonLatency.onClick.AddListener(OnPressedLatencyButton); buttonReplaceTrack.onClick.AddListener(OnPressedReplaceTrackButton); // This sample uses Compute Shader, so almost Android devices don't work correctly. if (!SystemInfo.supportsComputeShaders) { buttonLatency.interactable = false; } }
protected override void SetUpCodecCapability() { WebRTC.Initialize(); videoCodec = RTCRtpSender.GetCapabilities(TrackKind.Video).codecs.FirstOrDefault(c => c.mimeType.Contains("VP8")); WebRTC.Dispose(); }