public InitConfig(MediaKind mediaKind, TransceiverInitSettings settings) { name = settings?.Name; this.mediaKind = mediaKind; desiredDirection = (settings != null ? settings.InitialDesiredDirection : new TransceiverInitSettings().InitialDesiredDirection); encodedStreamIds = Utils.EncodeTransceiverStreamIDs(settings?.StreamIDs); }
public bool this[MediaKind kind] { get { var ret = kind switch { MediaKind.Audio => Audio, MediaKind.Video => Video, _ => false, }; return(ret); } set { switch (kind) { case MediaKind.Audio: Audio = value; break; case MediaKind.Video: Video = value; break; } } }
/// <summary> /// <para>Events:</para> /// <para>@emits transportclose</para></para> /// <para>@emits score - (score: ProducerScore[])</para> /// <para>@emits videoorientationchange - (videoOrientation: ProducerVideoOrientation)</para> /// <para>@emits trace - (trace: ProducerTraceEventData)</para> /// <para>@emits @close</para> /// <para>Observer events:</para> /// <para>@emits close</para> /// <para>@emits pause</para> /// <para>@emits resume</para> /// <para>@emits score - (score: ProducerScore[])</para> /// <para>@emits videoorientationchange - (videoOrientation: ProducerVideoOrientation)</para> /// <para>@emits trace - (trace: ProducerTraceEventData)</para> /// </summary> /// <param name="loggerFactory"></param> /// <param name="producerInternalData"></param> /// <param name="kind"></param> /// <param name="rtpParameters"></param> /// <param name="type"></param> /// <param name="consumableRtpParameters"></param> /// <param name="channel"></param> /// <param name="appData"></param> /// <param name="paused"></param> public Producer(ILoggerFactory loggerFactory, ProducerInternalData producerInternalData, MediaKind kind, RtpParameters rtpParameters, ProducerType type, RtpParameters consumableRtpParameters, Channel channel, Dictionary <string, object>?appData, bool paused) { _logger = loggerFactory.CreateLogger <Producer>(); // Internal Internal = producerInternalData; // Data Kind = kind; RtpParameters = rtpParameters; Type = type; ConsumableRtpParameters = consumableRtpParameters; _channel = channel; AppData = appData; Paused = paused; HandleWorkerNotifications(); }
/// <summary> /// <para>Events:</para> /// <para>@emits transportclose</para></para> /// <para>@emits score - (score: ProducerScore[])</para> /// <para>@emits videoorientationchange - (videoOrientation: ProducerVideoOrientation)</para> /// <para>@emits trace - (trace: ProducerTraceEventData)</para> /// <para>@emits @close</para> /// <para>Observer events:</para> /// <para>@emits close</para> /// <para>@emits pause</para> /// <para>@emits resume</para> /// <para>@emits score - (score: ProducerScore[])</para> /// <para>@emits videoorientationchange - (videoOrientation: ProducerVideoOrientation)</para> /// <para>@emits trace - (trace: ProducerTraceEventData)</para> /// </summary> /// <param name="loggerFactory"></param> /// <param name="producerInternalData"></param> /// <param name="kind"></param> /// <param name="rtpParameters"></param> /// <param name="type"></param> /// <param name="consumableRtpParameters"></param> /// <param name="channel"></param> /// <param name="appData"></param> /// <param name="paused"></param> public Producer(ILoggerFactory loggerFactory, ProducerInternalData producerInternalData, MediaKind kind, RtpParameters rtpParameters, ProducerType type, RtpParameters consumableRtpParameters, Channel channel, PayloadChannel payloadChannel, Dictionary <string, object>?appData, bool paused ) { _logger = loggerFactory.CreateLogger <Producer>(); // Internal _internal = producerInternalData; // Data Kind = kind; RtpParameters = rtpParameters; Type = type; ConsumableRtpParameters = consumableRtpParameters; _channel = channel; _payloadChannel = payloadChannel; AppData = appData; _paused = paused; _checkConsumersTimer = new Timer(CheckConsumers, null, TimeSpan.FromSeconds(CheckConsumersTimeSeconds), TimeSpan.FromMilliseconds(-1)); HandleWorkerNotifications(); }
/// <summary> /// <para>Events:</para> /// <para>@emits transportclose</para> /// <para>@emits producerclose</para> /// <para>@emits producerpause</para> /// <para>@emits producerresume</para> /// <para>@emits score - (score: ConsumerScore)</para> /// <para>@emits layerschange - (layers: ConsumerLayers | undefined)</para> /// <para>@emits trace - (trace: ConsumerTraceEventData)</para> /// <para>@emits @close</para> /// <para>@emits @producerclose</para> /// <para>Observer events:</para> /// <para>@emits close</para> /// <para>@emits pause</para> /// <para>@emits resume</para> /// <para>@emits score - (score: ConsumerScore)</para> /// <para>@emits layerschange - (layers: ConsumerLayers | undefined)</para> /// <para>@emits rtp - (packet: Buffer)</para> /// <para>@emits trace - (trace: ConsumerTraceEventData)</para> /// </summary> /// <param name="loggerFactory"></param> /// <param name="consumerInternalData"></param> /// <param name="kind"></param> /// <param name="rtpParameters"></param> /// <param name="type"></param> /// <param name="channel"></param> /// <param name="appData"></param> /// <param name="paused"></param> /// <param name="producerPaused"></param> /// <param name="score"></param> /// <param name="preferredLayers"></param> public Consumer(ILoggerFactory loggerFactory, ConsumerInternalData consumerInternalData, MediaKind kind, RtpParameters rtpParameters, ConsumerType type, Channel channel, PayloadChannel payloadChannel, Dictionary <string, object>?appData, bool paused, bool producerPaused, ConsumerScore?score, ConsumerLayers?preferredLayers ) { _logger = loggerFactory.CreateLogger <Consumer>(); // Internal _internal = consumerInternalData; // Data Kind = kind; RtpParameters = rtpParameters; Type = type; _channel = channel; _payloadChannel = payloadChannel; AppData = appData; _paused = paused; ProducerPaused = producerPaused; Score = score; PreferredLayers = preferredLayers; HandleWorkerNotifications(); }
/// <summary> /// Add a new media line of the given kind. /// /// This method creates a media line, which expresses an intent from the user to get a transceiver. /// The actual <see xref="WebRTC.Transceiver"/> object creation is delayed until a session /// negotiation is completed. /// /// Once the media line is created, the user can then assign its <see cref="MediaLine.Source"/> and /// <see cref="MediaLine.Receiver"/> properties to express their intent to send and/or receive some media /// through the transceiver that will be associated with that media line once a session is negotiated. /// This information is used in subsequent negotiations to derive a /// <see xref="Microsoft.MixedReality.WebRTC.Transceiver.Direction"/> to negotiate. Therefore users /// should avoid modifying the <see cref="Transceiver.DesiredDirection"/> property manually when using /// the Unity library, and instead modify the <see cref="MediaLine.Source"/> and /// <see cref="MediaLine.Receiver"/> properties. /// </summary> /// <param name="kind">The kind of media (audio or video) for the transceiver.</param> /// <returns>A newly created media line, which will be associated with a transceiver once the next session /// is negotiated.</returns> public MediaLine AddMediaLine(MediaKind kind) { var ml = new MediaLine(kind); _mediaLines.Add(ml); return(ml); }
void OnCollisionEnter(Collision collision) { if (collision.gameObject.CompareTag("Condition")) { ConditionActionK colK = collision.gameObject.GetComponent <ConditionAction>().MyKind; gameObject.GetComponent <MediaKind>().MyKind = colK; gameObject.tag = "ConditionMedia"; } else if (collision.gameObject.CompareTag("Action")) { ConditionActionK colK = collision.gameObject.GetComponent <ConditionAction>().MyKind; gameObject.GetComponent <MediaKind>().MyKind = colK; gameObject.tag = "ActionMedia"; } /*else if (collision.gameObject.CompareTag("Initial")) * { * MediaKind Inst = gameObject.GetComponent<MediaKind>(); * Inst.IsInitialMedia = !Inst.IsInitialMedia; * if (Inst.IsInitialMedia) { * controller.OnEntry(gameObject); * text.text = "Port " + Inst.MediaId; * } * else { * controller.RemoveEntry(gameObject); * text.text = "Port Removed "+ Inst.MediaId; * } * }*/ else if (collision.gameObject.CompareTag("Initial")) { MediaKind Inst = gameObject.GetComponent <MediaKind>(); if (!Inst.IsInitialMedia) { Inst.IsInitialMedia = true; controller.OnEntry(gameObject); text.text = "Port " + Inst.MediaId; } else { Inst.IsInitialMedia = false; controller.RemoveEntry(gameObject); } } else if (gameObject.CompareTag("ConditionMedia")) { MediaKind Inst = gameObject.GetComponent <MediaKind>(); MediaKind colInst = collision.gameObject.GetComponent <MediaKind>(); if (collision.gameObject.CompareTag("ActionMedia")) { /*Debug.Log( * Enum.GetName(typeof(ConditionActionK), Inst.MyKind) + " " + Inst.MediaId + " " + * Enum.GetName(typeof(ConditionActionK), colInst.MyKind) + " " + colInst.MediaId + " " * );*/ text.text = Enum.GetName(typeof(ConditionActionK), Inst.MyKind) + " " + Inst.MediaId + " " + Enum.GetName(typeof(ConditionActionK), colInst.MyKind) + " " + colInst.MediaId + " "; controller.CreateLink(gameObject, collision.gameObject); } } }
public TransceiverMetadata(string mid, MediaQuality quality, MediaKind kind, Guid sourceDeviceId) { Require.NotNullOrWhiteSpace(mid); Require.NotEmpty(sourceDeviceId); TransceiverMid = mid.Trim(); Quality = quality; Kind = kind; SourceDeviceId = sourceDeviceId; }
private void AddPendingTransceiver(MediaKind mediaKind, string name) { var settings = new TransceiverInitSettings { Name = name, InitialDesiredDirection = Transceiver.Direction.SendReceive, }; SessionModel.Current.AddTransceiver(mediaKind, settings); }
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); } }
/// <summary> /// Create a new transceiver associated with a given peer connection. /// </summary> /// <param name="handle">Handle to the native transceiver object.</param> /// <param name="mediaKind">The media kind of the transceiver and its tracks.</param> /// <param name="peerConnection">The peer connection owning this transceiver.</param> /// <param name="mlineIndex">The transceiver media line index in SDP.</param> /// <param name="name">The transceiver name.</param> /// <param name="streamIDs">Collection of stream IDs the transceiver is associated with, as set by the peer which created it.</param> /// <param name="initialDesiredDirection">Initial value to initialize <see cref="DesiredDirection"/> with.</param> internal Transceiver(TransceiverInterop.TransceiverHandle handle, MediaKind mediaKind, PeerConnection peerConnection, int mlineIndex, string name, string[] streamIDs, Direction initialDesiredDirection) { Debug.Assert(!handle.IsClosed); _nativeHandle = handle; MediaKind = mediaKind; PeerConnection = peerConnection; MlineIndex = mlineIndex; Name = name; StreamIDs = streamIDs; _desiredDirection = initialDesiredDirection; TransceiverInterop.RegisterCallbacks(this, out _argsRef); }
/// <summary> /// Gets the object item kind /// </summary> public static string GetObjectItem(MediaKind mediaKind) { switch (mediaKind) { case MediaKind.Video: return("videoItem.movie"); case MediaKind.Image: return("imageItem.photo"); case MediaKind.Audio: return("audioItem.musicTrack"); default: return("textItem"); } }
public void RefreshSenderList(MediaKind mediaKind, bool force = false) { if ((mediaKind != _availableMediaKind) || force) { _availableMediaKind = mediaKind; // Rebuild the list of sender tracks for the given media kind var senders = new ObservableCollection <SenderTrackViewModel>(); senders.Add(NullSenderTrack); if (_availableMediaKind == MediaKind.Audio) { foreach (var trackViewModel in SessionModel.Current.AudioTracks) { if (trackViewModel.IsRemote) { continue; } var track = trackViewModel?.TrackImpl; if (track != null) { senders.Add(new SenderTrackViewModel(track)); } } } else if (_availableMediaKind == MediaKind.Video) { foreach (var trackViewModel in SessionModel.Current.VideoTracks) { if (trackViewModel.IsRemote) { continue; } var track = trackViewModel?.TrackImpl; if (track != null) { senders.Add(new SenderTrackViewModel(track)); } } } AvailableSenders = senders; // FIXME - this is not thread-aware, and RefreshSenderList() can be called from non-UI thread... SelectedItem?.NotifySenderChanged(); } }
public RtpTransceiver AddTransceiver(MediaKind kind, RtpTransceiverDirection direction) { SafetyCheck(); if (kind == MediaKind.Data) { throw new NotSupportedException(); } var transceiverPtr = PeerConnectionInterop.AddTransceiver(_handle, kind == MediaKind.Audio, direction); if (transceiverPtr == IntPtr.Zero) { throw new AddTransceiverFailedException(); } var tmp = new RtpTransceiver(transceiverPtr, _signallingThread); _knownTransceivers.Add(transceiverPtr, tmp); return(tmp); }
void OnEnable() { autoInitOnStart_ = serializedObject.FindProperty("AutoInitializeOnStart"); autoCreateOffer_ = serializedObject.FindProperty("AutoCreateOfferOnRenegotiationNeeded"); autoLogErrors_ = serializedObject.FindProperty("AutoLogErrorsToUnityConsole"); iceServers_ = serializedObject.FindProperty("IceServers"); iceUsername_ = serializedObject.FindProperty("IceUsername"); iceCredential_ = serializedObject.FindProperty("IceCredential"); onInitialized_ = serializedObject.FindProperty("OnInitialized"); onShutdown_ = serializedObject.FindProperty("OnShutdown"); onError_ = serializedObject.FindProperty("OnError"); mediaLines_ = serializedObject.FindProperty("_mediaLines"); transceiverList_ = new ReorderableList(serializedObject, mediaLines_, true, true, true, true); transceiverList_.elementHeight = 2 * kLineHeight + kItemSpacing; transceiverList_.drawHeaderCallback = (Rect rect) => EditorGUI.LabelField(rect, "Transceivers"); transceiverList_.drawElementCallback = (Rect rect, int index, bool isActive, bool isFocused) => { var element = transceiverList_.serializedProperty.GetArrayElementAtIndex(index); float x0 = rect.x; float x1 = x0 + 16; float y0 = rect.y + 2; float y1 = y0 + kLineHeight; // MID value EditorGUI.LabelField(new Rect(x0, y0, 20, 20), $"{index}"); // Audio or video icon for transceiver kind MediaKind kind = (MediaKind)element.FindPropertyRelative("_kind").intValue; System.Type senderType, receiverType; if (kind == MediaKind.Audio) { senderType = typeof(AudioSender); receiverType = typeof(AudioReceiver); DrawSpriteIcon(IconType.Audio, new Rect(x1, rect.y, 20, 20)); } else { senderType = typeof(VideoSender); receiverType = typeof(VideoReceiver); DrawSpriteIcon(IconType.Video, new Rect(x1, rect.y, 20, 20)); } rect.x += kIconSpacing; rect.width -= kIconSpacing; rect.x += 18; rect.width -= 18; float fieldWidth = rect.width; bool hasSender = false; bool hasReceiver = false; { var p = element.FindPropertyRelative("_sender"); Object obj = p.objectReferenceValue; obj = EditorGUI.ObjectField( new Rect(rect.x, y0, fieldWidth, EditorGUIUtility.singleLineHeight), obj, senderType, true); hasSender = (obj != null); p.objectReferenceValue = obj; } { var p = element.FindPropertyRelative("_receiver"); Object obj = p.objectReferenceValue; obj = EditorGUI.ObjectField( new Rect(rect.x, y1, fieldWidth, EditorGUIUtility.singleLineHeight), obj, receiverType, true); hasReceiver = (obj != null); p.objectReferenceValue = obj; } IconType iconType = IconType.Inactive; if (hasSender) { if (hasReceiver) { iconType = IconType.SendRecv; } else { iconType = IconType.SendOnly; } } else if (hasReceiver) { iconType = IconType.RecvOnly; } DrawSpriteIcon(iconType, new Rect(x0 + 8, y1, 16, 16)); }; transceiverList_.drawNoneElementCallback = (Rect rect) => { GUIStyle style = new GUIStyle(EditorStyles.label); style.alignment = TextAnchor.MiddleCenter; EditorGUI.LabelField(rect, "(empty)", style); }; transceiverList_.displayAdd = false; }
public void SetMediaKind(MediaKind mediaKind) { Kind = mediaKind; }
//private static string noClue; public static void ReadFile(MP4File file) { try { title = file.Tags.Title; } catch { title = ""; } try { artist = file.Tags.Artist; } catch { artist = ""; } try { releaseDate = file.Tags.ReleaseDate; } catch { releaseDate = ""; } try { rating = (string)file.Tags.RatingInfo.Rating; } catch { rating = ""; } try { genre = file.Tags.Genre; } catch { genre = ""; } try { artwork = file.Tags.Artwork; } catch { artwork = null; } try { album = file.Tags.Album; } catch { album = ""; } try { albumArtist = file.Tags.AlbumArtist; } catch { albumArtist = ""; } try { purchaseDate = file.Tags.PurchasedDate; } catch { purchaseDate = ""; } try { shortDescription = file.Tags.Description; } catch { shortDescription = ""; } try { longDescription = file.Tags.LongDescription; } catch { longDescription = ""; } try { videoKind = file.Tags.MediaType; } catch { videoKind = 0; } try { if (file.Tags.MovieInfo.HasCast) { actors = String.Join(",", file.Tags.MovieInfo.Cast); } else { actors = ""; } } catch { actors = ""; } try { if (file.Tags.MovieInfo.HasDirectors) { director = String.Join(",", file.Tags.MovieInfo.Directors); } else { director = ""; } } catch { director = ""; } try { if (file.Tags.MovieInfo.HasScreenwriters) { screenwriter = String.Join(",", file.Tags.MovieInfo.Screenwriters); } else { screenwriter = ""; } } catch { screenwriter = ""; } try { show = file.Tags.TVShow; } catch { show = ""; } try { episodeId = file.Tags.EpisodeId; } catch { episodeId = ""; } try { season = (int)file.Tags.SeasonNumber; } catch { season = 0; } try { episode = (int)file.Tags.EpisodeNumber; } catch { episode = 0; } try { tvNetwork = file.Tags.TVNetwork; } catch { tvNetwork = ""; } try { isPodcast = (Boolean)file.Tags.IsPodcast; } catch { isPodcast = false; } feedUrl = ""; episodeUrl = ""; try { category = file.Tags.Category; } catch { category = ""; } try { keyword = file.Tags.Keywords; } catch { keyword = ""; } try { advisory = file.Tags.ContentRating; } catch { advisory = 0; } }
public RtpParameters GetSendingRtpParameters(MediaKind kind, ExtendedRtpCapabilities extendedRtpCapabilities) { List <RtpCodecParameters> codecs = new(); foreach (var extendedCodec in extendedRtpCapabilities.Codecs) { if (extendedCodec.Kind != kind) { continue; } RtpCodecParameters codec = new() { MimeType = extendedCodec.MimeType, PayloadType = extendedCodec.LocalPayloadType, ClockRate = extendedCodec.ClockRate, Channels = extendedCodec.Channels, Parameters = extendedCodec.LocalParameters, RtcpFeedback = extendedCodec.RtcpFeedback }; codecs.Add(codec); if (extendedCodec.LocalRtxPayloadType.HasValue) { RtpCodecParameters rtxCodec = new() { MimeType = $"{extendedCodec.Kind.DisplayName()}/rtx", PayloadType = (int)extendedCodec.LocalRtxPayloadType, ClockRate = extendedCodec.ClockRate, Parameters = new Dictionary <string, object> { { "apt", extendedCodec.LocalPayloadType } }, RtcpFeedback = new RtcpFeedback[] { } }; codecs.Add(rtxCodec); } } List <RtpHeaderExtensionParameters> headerExtensions = new(); foreach (var extendedExtendion in extendedRtpCapabilities.HeaderExtensions) { // Ignore RTP extensions of a different kind and those not valid for sending. if ((extendedExtendion.Kind != kind) || (extendedExtendion.Direction != Direction.SendRecv && extendedExtendion.Direction != Direction.SendOnly)) { continue; } RtpHeaderExtensionParameters ext = new() { Uri = extendedExtendion.Uri, Id = extendedExtendion.SendId, Encrypt = (bool)extendedExtendion.PreferredEncrypt, Parameters = new() }; headerExtensions.Add(ext); } return(new RtpParameters { Codecs = codecs.ToArray(), HeaderExtensions = headerExtensions.ToArray(), Encodings = new RtpEncodingParameters[] { }, Rtcp = new() }); }
public RtpParameters GetSendingRemoteRtpParameters(MediaKind kind, ExtendedRtpCapabilities extendedRtpCapabilities) { List <RtpCodecParameters> codecs = new(); foreach (var extendedCodec in extendedRtpCapabilities.Codecs) { if (extendedCodec.Kind != kind) { continue; } RtpCodecParameters codec = new() { MimeType = extendedCodec.MimeType, PayloadType = extendedCodec.LocalPayloadType, ClockRate = extendedCodec.ClockRate, Channels = extendedCodec.Channels, Parameters = extendedCodec.RemoteParameters, RtcpFeedback = extendedCodec.RtcpFeedback }; codecs.Add(codec); if (extendedCodec.LocalRtxPayloadType.HasValue) { RtpCodecParameters rtxCodec = new() { MimeType = $"{extendedCodec.Kind.DisplayName()}/rtx", PayloadType = (int)extendedCodec.LocalRtxPayloadType, ClockRate = extendedCodec.ClockRate, Parameters = new Dictionary <string, object> { { "apt", extendedCodec.LocalPayloadType } }, RtcpFeedback = new RtcpFeedback[] { } }; codecs.Add(rtxCodec); } } List <RtpHeaderExtensionParameters> headerExtensions = new(); foreach (var extendedExtendion in extendedRtpCapabilities.HeaderExtensions) { // Ignore RTP extensions of a different kind and those not valid for sending. if ((extendedExtendion.Kind != kind) || (extendedExtendion.Direction != Direction.SendRecv && extendedExtendion.Direction != Direction.SendOnly)) { continue; } RtpHeaderExtensionParameters ext = new() { Uri = extendedExtendion.Uri, Id = extendedExtendion.SendId, Encrypt = (bool)extendedExtendion.PreferredEncrypt, }; headerExtensions.Add(ext); } // Reduce codecs' RTCP feedback. Use Transport-CC if available, REMB otherwise. if (headerExtensions.Any(ext => ext.Uri == "http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01")) { foreach (var codec in codecs) { codec.RtcpFeedback = codec.RtcpFeedback .Where(fb => fb.Type != "goog-remb").ToArray(); } } else if (headerExtensions.Any(ext => ext.Uri == "http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time")) { foreach (var codec in codecs) { codec.RtcpFeedback = codec.RtcpFeedback .Where(fb => fb.Type != "transport-cc").ToArray(); } } else { foreach (var codec in codecs) { codec.RtcpFeedback = codec.RtcpFeedback .Where(fb => fb.Type != "transport-cc" && fb.Type != "goog-remb").ToArray(); } } return(new RtpParameters { Codecs = codecs.ToArray(), HeaderExtensions = headerExtensions.ToArray(), Encodings = new RtpEncodingParameters[] { }, Rtcp = new() }); }
public bool CanSend(MediaKind kind, ExtendedRtpCapabilities extendedRtpCapabilities) { return(extendedRtpCapabilities.Codecs.Any(codec => codec.Kind == kind)); }
/// <summary> /// Create a new media source of the given <see cref="MediaKind"/>. /// </summary> /// <param name="mediaKind">The media kind of the source.</param> public MediaSource(MediaKind mediaKind) { MediaKind = mediaKind; }
public Task <IList <IMediaDevice> > GetMediaDevicesAsync(MediaKind kind) { if (kind == MediaKind.AudioInputDevice) { return(Task.Run(async() => { IList <IMediaDevice> audioMediaDevicesCapturersList = new List <IMediaDevice>(); DeviceInformationCollection audioCapturers = await DeviceInformation.FindAllAsync(Windows.Media.Devices.MediaDevice.GetAudioCaptureSelector()); foreach (var microphone in audioCapturers) { var mediaDevice = new MediaDevice(); mediaDevice.GetMediaKind(MediaKind.AudioInputDevice.ToString()); mediaDevice.GetId(microphone.Id); mediaDevice.GetDisplayName(microphone.Name); audioMediaDevicesCapturersList.Add(mediaDevice); } return audioMediaDevicesCapturersList; })); } if (kind == MediaKind.AudioOutputDevice) { return(Task.Run(async() => { IList <IMediaDevice> audioMediaDevicesRendersList = new List <IMediaDevice>(); DeviceInformationCollection audioRenders = await DeviceInformation.FindAllAsync(Windows.Media.Devices.MediaDevice.GetAudioRenderSelector()); foreach (var speaker in audioRenders) { var mediaDevice = new MediaDevice(); mediaDevice.GetMediaKind(MediaKind.AudioOutputDevice.ToString()); mediaDevice.GetId(speaker.Id); mediaDevice.GetDisplayName(speaker.Name); audioMediaDevicesRendersList.Add(mediaDevice); } return audioMediaDevicesRendersList; })); } if (kind == MediaKind.VideoDevice) { return(Task.Run(async() => { IList <IMediaDevice> videoMediaDevicesList = new List <IMediaDevice>(); IReadOnlyList <IVideoDeviceInfo> videoDevices = await VideoCapturer.GetDevices(); foreach (IVideoDeviceInfo videoDevice in videoDevices) { var mediaDevice = new MediaDevice(); mediaDevice.GetMediaKind(MediaKind.VideoDevice.ToString()); mediaDevice.GetId(videoDevice.Info.Id); mediaDevice.GetDisplayName(videoDevice.Info.Name); IList <MediaVideoFormat> videoFormatsList = await GetMediaVideoFormatList(videoDevice.Info.Id); mediaDevice.GetVideoFormats(videoFormatsList); videoMediaDevicesList.Add(mediaDevice); } return videoMediaDevicesList; })); } else { return(null); } }
/// <summary> /// Constructor called internally by <see cref="PeerConnection.AddMediaLine(MediaKind)"/>. /// </summary> /// <param name="kind">Immutable value assigned to the <see cref="MediaKind"/> property on construction.</param> internal MediaLine(PeerConnection peer, MediaKind kind) { _peer = peer; _mediaKind = kind; }
/// <summary> /// Parses the Show specific data from the input string and the match. /// </summary> /// <param name="input">Input string</param> /// <param name="match">The returned matches for the regexes.</param> /// <param name="dir">Switch whenever it is a directory name.</param> /// <param name="AirDateInName">Switch whenever the date regex matched.</param> private void ParseShow(String input, Match match, Boolean dir = false, Boolean AirDateInName = false) { mediaKind = EMP.MediaKind.Show; //String inputCl = helperDictionary.CleanFileName(input);//unnneeded GroupCollection groups = match.Groups; #region Season, Episode or AirDate if (match.Length > 0) Index.Add(new StringLocation(match.ToString(), match.Index, match.Length, false, dir)); if (AirDateInName) { if (airDate == null) { DateTime.TryParse(match.ToString(), out airDate); } } else { if (season == 0) { if (!Int16.TryParse(groups[1].ToString(), out season) || groups[1].ToString().Trim() == String.Empty) { Int16.TryParse(groups[3].ToString(), out season); } } if (episode == 0) { if (!Int16.TryParse(groups[2].ToString(), out episode) || groups[2].ToString().Trim() == String.Empty) { Int16.TryParse(groups[4].ToString(), out episode); } } } #endregion //title is series and the shit in between episode number and the rest is series title. #region Series, Title & Other #endregion }
/// <summary> /// Parses the Movie specific data from the input string. /// </summary> /// <param name="input">Input string</param> /// <param name="dir">Switch whenever it is a directory name.</param> private void ParseMovie(String input, Boolean dir = false) { mediaKind = EMP.MediaKind.Movie; String inputCl = helperDictionary.CleanFileName(input); Int32 TmpStart; String TmpString; #region year //A little regex for recognizing the year Regex rgx = new Regex(@"((19|20)\d{2})"); if (rgx.IsMatch(input)) { if (year == 0) { Match match = rgx.Matches(inputCl)[rgx.Matches(input).Count - 1]; TmpString = match.ToString(); if (match.Length > 0) Index.Add(new StringLocation(TmpString, match.Index, match.Length, true, dir)); Int32.TryParse(TmpString, out year); } } #endregion #region cut if (cut == Cut.Final) { TmpString = Check(inputCl, helperDictionary.CutStrings, out TmpStart); cut = helperDictionary.StrToCut(TmpString); if (TmpString.Length > 0) Index.Add(new StringLocation(TmpString, TmpStart, TmpString.Length, true, dir)); } #endregion #region IMDBid if (imdbid == String.Empty || imdbid == null) { // Here we call Regex.Match. Match match = Regex.Match(input, @"tt[0-9]{7}", RegexOptions.IgnoreCase); // Here we check the Match instance. if (match.Success) { // Finally, we get the Group value and display it. imdbid = match.Value; Index.Add(new StringLocation(match.Value, match.Index, match.Length, false, dir)); } } #endregion }
/// <inheritdoc/> public MediaSender(MediaKind mediaKind) : base(mediaKind) { }
/// <summary> /// Constructor called internally by <see cref="PeerConnection.AddMediaLine(MediaKind)"/>. /// </summary> /// <param name="kind">Immutable value assigned to the <see cref="MediaKind"/> property on construction.</param> internal MediaLine(MediaKind kind) { _mediaKind = kind; }
public Transceiver AddTransceiver(MediaKind mediaKind, TransceiverInitSettings settings) { // This will raise the TransceiverAdded event, which adds a new view model // for the newly added transceiver automatically. return(_peerConnection.AddTransceiver(mediaKind, settings)); }
public Task AddTransceivers_TransceiverAddedExplicitly_ReturnsTransceiverWithCorrectMediaKind(MediaKind mediaKind) { return(_signallingThread.ExecuteAsync(delegate { using (var peerConnectionObserver = new PeerConnectionObserver()) using (var peerConnection = _peerConnectionFactory.CreatePeerConnection(peerConnectionObserver, _config)) using (var transceiver = peerConnection.AddTransceiver(mediaKind, RtpTransceiverDirection.SendOnly)) { Assert.NotNull(transceiver); Assert.Equal(mediaKind, transceiver.MediaKind); } })); }
/// <inheritdoc/> public MediaReceiver(MediaKind mediaKind) : base(mediaKind) { }
public TransceiverTests(SdpSemantic sdpSemantic, MediaKind mediaKind) : base(sdpSemantic) { MediaKind = mediaKind; }
void OnEnable() { autoCreateOffer_ = serializedObject.FindProperty("AutoCreateOfferOnRenegotiationNeeded"); autoLogErrors_ = serializedObject.FindProperty("AutoLogErrorsToUnityConsole"); iceServers_ = serializedObject.FindProperty("IceServers"); iceUsername_ = serializedObject.FindProperty("IceUsername"); iceCredential_ = serializedObject.FindProperty("IceCredential"); onInitialized_ = serializedObject.FindProperty("OnInitialized"); onShutdown_ = serializedObject.FindProperty("OnShutdown"); onError_ = serializedObject.FindProperty("OnError"); mediaLines_ = serializedObject.FindProperty("_mediaLines"); transceiverList_ = new ReorderableList(serializedObject, mediaLines_, draggable: true, displayHeader: true, displayAddButton: false, displayRemoveButton: true); transceiverList_.elementHeightCallback = (int index) => { float height = kItemSpacing + 2 * kLineHeight; var element = transceiverList_.serializedProperty.GetArrayElementAtIndex(index); var src = element.FindPropertyRelative("_source"); if (src.isExpanded) { var trackName = element.FindPropertyRelative("SenderTrackName"); // FIXME - SdpTokenDrawer.OnGUI() is called with h=16px instead of the total height, breaking the layout height += kLineHeight; // EditorGUI.GetPropertyHeight(trackName) + kItemSpacing; } return(height); }; transceiverList_.drawHeaderCallback = (Rect rect) => EditorGUI.LabelField(rect, "Transceivers"); transceiverList_.drawElementCallback = (Rect rect, int index, bool isActive, bool isFocused) => { var element = transceiverList_.serializedProperty.GetArrayElementAtIndex(index); float x0 = rect.x; float x1 = x0 + 16; float y0 = rect.y + 2; float y1 = y0 + kLineHeight; // MID value EditorGUI.LabelField(new Rect(x0 - 14, y1, 20, 20), $"{index}"); // Audio or video icon for transceiver kind MediaKind mediaKind = (MediaKind)element.FindPropertyRelative("_mediaKind").intValue; System.Type senderType, receiverType; if (mediaKind == MediaKind.Audio) { senderType = typeof(AudioTrackSource); receiverType = typeof(AudioReceiver); DrawSpriteIcon(IconType.Audio, new Rect(x0, rect.y, 20, 20)); } else { senderType = typeof(VideoTrackSource); receiverType = typeof(VideoReceiver); DrawSpriteIcon(IconType.Video, new Rect(x0, rect.y, 20, 20)); } rect.x += (kIconSpacing + 10); rect.width -= (kIconSpacing + 10); float fieldWidth = rect.width; bool hasSender = false; bool hasReceiver = false; bool sourceIsExpanded = false; { var p = element.FindPropertyRelative("_source"); Object obj = p.objectReferenceValue; sourceIsExpanded = EditorGUI.Foldout(new Rect(rect.x, y0, 0, EditorGUIUtility.singleLineHeight), p.isExpanded, new GUIContent()); p.isExpanded = sourceIsExpanded; obj = EditorGUI.ObjectField( new Rect(rect.x, y0, fieldWidth, EditorGUIUtility.singleLineHeight), obj, senderType, true); hasSender = (obj != null); p.objectReferenceValue = obj; y0 += kLineHeight; } if (sourceIsExpanded) { var p = element.FindPropertyRelative("_senderTrackName"); // FIXME - SdpTokenDrawer.OnGUI() is called with h=16px instead of the total height, breaking the layout //EditorGUI.PropertyField(new Rect(rect.x + 10, y0, fieldWidth - 8, EditorGUIUtility.singleLineHeight), p); //y0 += EditorGUI.GetPropertyHeight(p) + 6; string val = p.stringValue; val = EditorGUI.TextField(new Rect(rect.x + 10, y0, fieldWidth - 8, EditorGUIUtility.singleLineHeight), "Track name", val); p.stringValue = val; y0 += kLineHeight; } { var p = element.FindPropertyRelative("_receiver"); Object obj = p.objectReferenceValue; obj = EditorGUI.ObjectField( new Rect(rect.x, y0, fieldWidth, EditorGUIUtility.singleLineHeight), obj, receiverType, true); hasReceiver = (obj != null); p.objectReferenceValue = obj; } IconType iconType = IconType.Inactive; if (hasSender) { if (hasReceiver) { iconType = IconType.SendRecv; } else { iconType = IconType.SendOnly; } } else if (hasReceiver) { iconType = IconType.RecvOnly; } DrawSpriteIcon(iconType, new Rect(x0, y1, 16, 16)); }; transceiverList_.drawNoneElementCallback = (Rect rect) => { GUIStyle style = new GUIStyle(EditorStyles.label); style.alignment = TextAnchor.MiddleCenter; EditorGUI.LabelField(rect, "(empty)", style); }; }
//readonly SctpParameters _sctpParameters; //readonly PlainRtpParameters _plainRtpParameters; //readonly Mid _mid; //readonly MediaKind _kind; //RtpParameters public OfferMediaSection( IceParameters iceParameters, IceCandidate[] iceCandidates, DtlsParameters dtlsParameters, SctpParameters sctpParameters, PlainRtpParameters plainRtpParameters, bool planB, Mid mid, MediaKind kind, RtpParameters offerRtpParameters, string streamId, string trackId, bool oldDataChannelSpec) : base(iceParameters, iceCandidates, dtlsParameters, planB) { _mediaObject.MediaDescription.Attributes.Mid = mid; _mediaObject.MediaDescription.Media = kind.ToSdp(); if (plainRtpParameters is null) { _mediaObject.MediaDescription.ConnectionData = new ConnectionData { NetType = NetType.Internet, AddrType = AddrType.Ip4, ConnectionAddress = "127.0.0.1" }; if (sctpParameters is null) { _mediaObject.MediaDescription.Proto = "UDP/TLS/RTP/SAVPF"; } else { _mediaObject.MediaDescription.Proto = "UDP/DTLS/SCTP"; } _mediaObject.MediaDescription.Port = 7; } else { _mediaObject.MediaDescription.ConnectionData = new ConnectionData { NetType = NetType.Internet, AddrType = plainRtpParameters.IpVersion, ConnectionAddress = plainRtpParameters.Ip }; _mediaObject.MediaDescription.Proto = "RTP/AVP"; _mediaObject.MediaDescription.Port = plainRtpParameters.Port; } switch (kind) { case MediaKind.Audio: case MediaKind.Video: { _mediaObject.MediaDescription.Attributes.SendOnly = true; _mediaObject.MediaDescription.Attributes.Rtpmaps = new List <Rtpmap>(); _mediaObject.MediaDescription.Attributes.RtcpFbs = new List <RtcpFb>(); _mediaObject.MediaDescription.Attributes.Fmtps = new List <Fmtp>(); if (!_planB) { _mediaObject.MediaDescription.Attributes.Msid = new() { Id = streamId ?? "-", AppData = trackId } } ; foreach (var codec in offerRtpParameters.Codecs) { Rtpmap rtpmap = new() { PayloadType = codec.PayloadType, EncodingName = GetCodecName(codec), ClockRate = codec.ClockRate, Channels = codec.Channels > 1 ? codec.Channels : null }; _mediaObject.MediaDescription.Attributes.Rtpmaps.Add(rtpmap); Fmtp fmtp = codec.Parameters.ToFmtp(codec.PayloadType); if (!string.IsNullOrEmpty(fmtp.Value)) { _mediaObject.MediaDescription.Attributes.Fmtps.Add(fmtp); } foreach (var fb in codec.RtcpFeedback) { RtcpFb rtcpFb = new() { PayloadType = codec.PayloadType, Type = fb.Type, SubType = fb.Parameter }; _mediaObject.MediaDescription.Attributes.RtcpFbs.Add(rtcpFb); } } _mediaObject.MediaDescription.Fmts ??= new List <string>(); ((List <string>)_mediaObject.MediaDescription.Fmts).AddRange(offerRtpParameters.Codecs .Select(codec => codec.PayloadType.ToString())); _mediaObject.MediaDescription.Attributes.Extmaps = new List <Extmap>(); foreach (var headerExtension in offerRtpParameters.HeaderExtensions) { Extmap ext = new() { Uri = new Uri(headerExtension.Uri), Value = headerExtension.Id }; _mediaObject.MediaDescription.Attributes.Extmaps.Add(ext); } _mediaObject.MediaDescription.Attributes.RtcpMux = true; _mediaObject.MediaDescription.Attributes.RtcpRsize = true; var encoding = offerRtpParameters.Encodings[0]; var ssrc = encoding.Ssrc; var rtxSsrc = (encoding.Rtx is not null && encoding.Rtx.Ssrc.HasValue) ? encoding.Rtx.Ssrc : null; _mediaObject.MediaDescription.Attributes.Ssrcs = new List <Ssrc>(); _mediaObject.MediaDescription.Attributes.SsrcGroups = new List <SsrcGroup>(); if (offerRtpParameters.Rtcp.Cname is not null) { _mediaObject.MediaDescription.Attributes.Ssrcs.Add(new Ssrc { Id = (uint)ssrc, Attribute = "cname", Value = offerRtpParameters.Rtcp.Cname }); } if (_planB) { _mediaObject.MediaDescription.Attributes.Ssrcs.Add(new Ssrc { Id = (uint)ssrc, Attribute = "msid", Value = $"{streamId ?? "-"} {trackId}" }); } if (rtxSsrc.HasValue) { if (offerRtpParameters.Rtcp.Cname is not null) { _mediaObject.MediaDescription.Attributes.Ssrcs.Add(new Ssrc { Id = (uint)rtxSsrc, Attribute = "cname", Value = offerRtpParameters.Rtcp.Cname }); } if (_planB) { _mediaObject.MediaDescription.Attributes.Ssrcs.Add(new Ssrc { Id = (uint)rtxSsrc, Attribute = "msid", Value = $"{streamId ?? "-"} {trackId}" }); } // Associate original and retransmission SSRCs. _mediaObject.MediaDescription.Attributes.SsrcGroups.Add(new SsrcGroup { Semantics = "FID", SsrcIds = new string[] { $"{ssrc} {rtxSsrc}" } }); } break; } case MediaKind.Application: { // New spec. if (!oldDataChannelSpec) { _mediaObject.MediaDescription.Fmts = new List <string> { "webrtc-datachannel" }; _mediaObject.MediaDescription.Attributes.SctpPort = new SctpPort { Port = sctpParameters.Port }; _mediaObject.MediaDescription.Attributes.MaxMessageSize = new MaxMessageSize { Size = sctpParameters.MaxMessageSize }; } // Old spec. else { _mediaObject.MediaDescription.Fmts = new List <string> { sctpParameters.Port.ToString() }; _mediaObject.SctpMap = new() { App = "webrtc-datachannel", SctpMapNumber = sctpParameters.Port, MaxMessageSize = sctpParameters.MaxMessageSize }; } break; } } } void PlanBReceive(RtpParameters offerRtpParameters, string streamId, IMediaStream trackId) { var encoding = offerRtpParameters.Encodings[0]; var ssrc = encoding.Ssrc; var rtxSsrc = (encoding.Rtx is not null && encoding.Rtx.Ssrc.HasValue) ? encoding.Rtx.Ssrc : null; var payloads = _mediaObject.MediaDescription.Fmts.ToArray(); foreach (var codec in offerRtpParameters.Codecs) { if (payloads.Any(payload => payload.Contains(codec.PayloadType.ToString()))) { continue; } Rtpmap rtpmap = new() { PayloadType = codec.PayloadType, EncodingName = GetCodecName(codec), ClockRate = codec.ClockRate, Channels = codec.Channels > 1 ? codec.Channels : null }; _mediaObject.MediaDescription.Attributes.Rtpmaps.Add(rtpmap); Fmtp fmtp = codec.Parameters.ToFmtp(codec.PayloadType); if (!string.IsNullOrEmpty(fmtp.Value)) { _mediaObject.MediaDescription.Attributes.Fmtps.Add(fmtp); } foreach (var fb in codec.RtcpFeedback) { RtcpFb rtcpFb = new() { PayloadType = codec.PayloadType, Type = fb.Type, SubType = fb.Parameter }; _mediaObject.MediaDescription.Attributes.RtcpFbs.Add(rtcpFb); } } ((List <string>)_mediaObject.MediaDescription.Fmts).AddRange(offerRtpParameters.Codecs .Select(codec => codec.PayloadType.ToString())); if (offerRtpParameters.Rtcp.Cname is not null) { _mediaObject.MediaDescription.Attributes.Ssrcs.Add(new Ssrc { Id = (uint)ssrc, Attribute = "cname", Value = offerRtpParameters.Rtcp.Cname }); } _mediaObject.MediaDescription.Attributes.Ssrcs.Add(new Ssrc { Id = (uint)ssrc, Attribute = "msid", Value = $"{streamId ?? "-"} {trackId}" }); if (rtxSsrc.HasValue) { if (offerRtpParameters.Rtcp.Cname is not null) { _mediaObject.MediaDescription.Attributes.Ssrcs.Add(new Ssrc { Id = (uint)rtxSsrc, Attribute = "cname", Value = offerRtpParameters.Rtcp.Cname }); } _mediaObject.MediaDescription.Attributes.Ssrcs.Add(new Ssrc { Id = (uint)rtxSsrc, Attribute = "msid", Value = $"{streamId ?? "-"} {trackId}" }); // Associate original and retransmission SSRCs. _mediaObject.MediaDescription.Attributes.SsrcGroups.Add(new SsrcGroup { Semantics = "FID", SsrcIds = new string[] { $"{ssrc} {rtxSsrc}" } }); } } public void PlanBReceive(RtpParameters offerRtpParameters, string streamId, string trackId) { var encoding = offerRtpParameters.Encodings[0]; var ssrc = encoding.Ssrc; var rtxSsrc = (encoding.Rtx is not null && encoding.Rtx.Ssrc.HasValue) ? encoding.Rtx.Ssrc : null; var payloads = _mediaObject.MediaDescription.Fmts.ToArray(); foreach (var codec in offerRtpParameters.Codecs) { if (payloads.Contains(codec.PayloadType.ToString())) { continue; } Rtpmap rtpmap = new() { PayloadType = codec.PayloadType, EncodingName = GetCodecName(codec), ClockRate = codec.ClockRate, Channels = codec.Channels > 1 ? codec.Channels : null }; _mediaObject.MediaDescription.Attributes.Rtpmaps.Add(rtpmap); Fmtp fmtp = codec.Parameters.ToFmtp(codec.PayloadType); if (!string.IsNullOrEmpty(fmtp.Value)) { _mediaObject.MediaDescription.Attributes.Fmtps.Add(fmtp); } foreach (var fb in codec.RtcpFeedback) { _mediaObject.MediaDescription.Attributes.RtcpFbs.Add(new RtcpFb { PayloadType = codec.PayloadType, Type = fb.Type, SubType = fb.Parameter }); } } ((List <string>)_mediaObject.MediaDescription.Fmts).AddRange(offerRtpParameters.Codecs .Where(codec => !_mediaObject.MediaDescription.Fmts.Contains(codec.PayloadType.ToString())) .Select(codec => codec.PayloadType.ToString()) .ToArray()); if (offerRtpParameters.Rtcp.Cname is not null) { _mediaObject.MediaDescription.Attributes.Ssrcs.Add(new Ssrc { Id = (uint)ssrc, Attribute = "cname", Value = offerRtpParameters.Rtcp.Cname }); } _mediaObject.MediaDescription.Attributes.Ssrcs.Add(new Ssrc { Id = (uint)ssrc, Attribute = "msid", Value = $"{ streamId ?? "-"} { trackId}" }); if (rtxSsrc is not null) { if (offerRtpParameters.Rtcp.Cname is not null) { _mediaObject.MediaDescription.Attributes.Ssrcs.Add(new Ssrc { Id = (uint)rtxSsrc, Attribute = "cname", Value = offerRtpParameters.Rtcp.Cname }); } _mediaObject.MediaDescription.Attributes.Ssrcs.Add(new Ssrc { Id = (uint)rtxSsrc, Attribute = "msid", Value = $"{ streamId ?? "-"} {trackId}" }); // Associate original and retransmission SSRCs. _mediaObject.MediaDescription.Attributes.SsrcGroups.Add(new SsrcGroup { Semantics = "FID", SsrcIds = new string[] { $"{ ssrc }${rtxSsrc}" } }); } } void PlanBStopReceiving(RtpParameters offerRtpParameters) { var encoding = offerRtpParameters.Encodings[0]; var ssrc = encoding.Ssrc; var rtxSsrc = (encoding.Rtx is not null && encoding.Rtx.Ssrc.HasValue) ? encoding.Rtx.Ssrc : null; ((List <Ssrc>)_mediaObject.MediaDescription.Attributes.Ssrcs).RemoveAll(s => s.Id != ssrc && s.Id != rtxSsrc); if (rtxSsrc is not null) { ((List <SsrcGroup>)_mediaObject.MediaDescription.Attributes.SsrcGroups).RemoveAll(g => g.SsrcIds.Any(id => id != $"{ssrc} {rtxSsrc}")); } } public override void SetDtlsRole(DtlsRole?dtlsRole)