Example #1
0
 public void AddVideoTrack(LocalVideoTrack track, string deviceName)
 {
     ThreadHelper.EnsureIsMainThread();
     VideoTracks.Add(new VideoTrackViewModel(track, deviceName));
     LocalTracks.Add(new LocalTrackViewModel(Symbol.Video)
     {
         DisplayName = deviceName
     });
 }
Example #2
0
        /// <summary>
        /// Callback on remote videa track added.
        ///
        /// For simplicity this grabs the first remote video track found and uses it to render its
        /// content on the right pane of the Tracks window.
        /// </summary>
        /// <param name="track">The video track added.</param>
        /// <seealso cref="RemoteVideoTrack_I420AFrameReady"/>
        private void OnRemoteVideoTrackAdded(RemoteVideoTrack track)
        {
            Logger.Log($"Added remote video track {track.Name} of transceiver {track.Transceiver.Name}.");

            ThreadHelper.RunOnMainThread(() =>
            {
                var trvm = Transceivers.SingleOrDefault(tr => tr.Transceiver == track.Transceiver);
                Debug.Assert(trvm.Transceiver.RemoteVideoTrack == track);
                trvm.NotifyReceiverChanged(); // this is thread-aware
                // This raises property changed events in current thread, needs to be main one
                VideoTracks.Add(new VideoTrackViewModel(track));
            });
        }
Example #3
0
        /// <summary>
        /// Callback on remote video track removed.
        /// </summary>
        /// <param name="track">The video track removed.</param>
        private void OnRemoteVideoTrackRemoved(Transceiver transceiver, RemoteVideoTrack track)
        {
            Logger.Log($"Removed remote video track {track.Name} from transceiver {transceiver.Name}.");

            var vtvm = VideoTracks.Single(vm => vm.TrackImpl == track);

            VideoTracks.Remove(vtvm);

            //IVideoTrack newPlaybackVideoTrack = null;
            //if (LocalVideoTracks.Count > 0)
            //{
            //    newPlaybackVideoTrack = LocalVideoTracks[0].Track;
            //}
            //else
            //{
            //    videoTrackComboBox.IsEnabled = false;
            //    _videoStatsTimer.Stop();
            //}
            //SwitchMediaPlayerSource(_playbackAudioTrack, newPlaybackVideoTrack);
        }
Example #4
0
        private SessionModel()
        {
            _peerConnection.Connected                += OnPeerConnected;
            _peerConnection.LocalSdpReadytoSend      += OnLocalSdpReadyToSend;
            _peerConnection.IceCandidateReadytoSend  += OnIceCandidateReadyToSend;
            _peerConnection.IceStateChanged          += OnIceStateChanged;
            _peerConnection.IceGatheringStateChanged += OnIceGatheringStateChanged;
            _peerConnection.RenegotiationNeeded      += OnRenegotiationNeeded;
            _peerConnection.TransceiverAdded         += OnTransceiverAdded;
            _peerConnection.AudioTrackAdded          += OnRemoteAudioTrackAdded;
            _peerConnection.AudioTrackRemoved        += OnRemoteAudioTrackRemoved;
            _peerConnection.VideoTrackAdded          += OnRemoteVideoTrackAdded;
            _peerConnection.VideoTrackRemoved        += OnRemoteVideoTrackRemoved;
            _peerConnection.DataChannelAdded         += OnDataChannelAdded;
            _peerConnection.DataChannelRemoved       += OnDataChannelRemoved;

            NodeDssSignaler.OnConnect     += DssSignaler_OnConnected;
            NodeDssSignaler.OnDisconnect  += DssSignaler_OnDisconnected;
            NodeDssSignaler.OnMessage     += DssSignaler_OnMessage;
            NodeDssSignaler.OnFailure     += DssSignaler_OnFailure;
            NodeDssSignaler.OnPollingDone += DssSignaler_OnPollingDone;

            AudioTracks.Add(NullAudioTrack);
            VideoTracks.Add(NullVideoTrack);

            AudioTracks.CollectionChanged += LocalAudioTrackCollectionChanged;
            VideoTracks.CollectionChanged += LocalVideoTrackCollectionChanged;

            LocalTracks.Add(new AddNewTrackViewModel()
            {
                DisplayName = "Add audio track", PageType = typeof(AddAudioTrackPage)
            });
            LocalTracks.Add(new AddNewTrackViewModel()
            {
                DisplayName = "Add video track", PageType = typeof(AddVideoTrackPage)
            });
        }
        private void OnInspectorGUI_MediaInfo()
        {
            MediaPlayer   media       = (this.target) as MediaPlayer;
            IMediaInfo    info        = media.Info;
            IMediaControl control     = media.Control;
            ITextTracks   textTracks  = media.TextTracks;
            IAudioTracks  audioTracks = media.AudioTracks;
            IVideoTracks  videoTracks = media.VideoTracks;

            if (info != null)
            {
                if (!info.HasVideo() && !info.HasAudio())                // && !info.HasText())
                {
                    GUILayout.Label("No media loaded");
                }
                else
                {
                    if (info.HasVideo())
                    {
                        GUILayout.BeginHorizontal();
                        {
                            string dimensionText = string.Format("{0}x{1}@{2:0.##}", info.GetVideoWidth(), info.GetVideoHeight(), info.GetVideoFrameRate());
                            GUILayout.Label(dimensionText);
                            GUILayout.FlexibleSpace();
                            string rateText = "0.00";
                            if (media.Info != null)
                            {
                                rateText = media.Info.GetVideoDisplayRate().ToString("F2");
                            }
                            GUILayout.Label(rateText + "FPS");
                        }
                        GUILayout.EndHorizontal();

                        EditorGUILayout.Space();
                    }
                    if (info.HasVideo())
                    {
                        VideoTracks tracks = videoTracks.GetVideoTracks();
                        if (tracks.Count > 0)
                        {
                            GUILayout.Label("Video Tracks: " + tracks.Count);
                            foreach (VideoTrack track in tracks)
                            {
                                bool isActiveTrack = (track == videoTracks.GetActiveVideoTrack());
                                GUI.color = isActiveTrack?Color.green:Color.white;
                                {
                                    if (GUILayout.Button(track.DisplayName))
                                    {
                                        if (isActiveTrack)
                                        {
                                            videoTracks.SetActiveVideoTrack(null);
                                        }
                                        else
                                        {
                                            videoTracks.SetActiveVideoTrack(track);
                                        }
                                    }
                                }
                            }
                            GUI.color = Color.white;
                            EditorGUILayout.Space();
                        }
                    }
                    if (info.HasAudio())
                    {
                        AudioTracks tracks = audioTracks.GetAudioTracks();
                        if (tracks.Count > 0)
                        {
                            GUILayout.Label("Audio Tracks: " + tracks.Count);
                            foreach (AudioTrack track in tracks)
                            {
                                bool isActiveTrack = (track == audioTracks.GetActiveAudioTrack());
                                GUI.color = isActiveTrack?Color.green:Color.white;
                                {
                                    if (GUILayout.Button(track.DisplayName))
                                    {
                                        if (isActiveTrack)
                                        {
                                            audioTracks.SetActiveAudioTrack(null);
                                        }
                                        else
                                        {
                                            audioTracks.SetActiveAudioTrack(track);
                                        }
                                    }
                                }
                            }
                            GUI.color = Color.white;

                            /*int channelCount = control.GetAudioChannelCount();
                             * if (channelCount > 0)
                             * {
                             *      GUILayout.Label("Audio Channels: " + channelCount);
                             *      AudioChannelMaskFlags audioChannels = control.GetAudioChannelMask();
                             *      GUILayout.Label("(" + audioChannels + ")", EditorHelper.IMGUI.GetWordWrappedTextAreaStyle());
                             * }*/
                            EditorGUILayout.Space();
                        }
                    }
                    {
                        TextTracks tracks = textTracks.GetTextTracks();
                        if (tracks.Count > 0)
                        {
                            GUILayout.Label("Text Tracks: " + tracks.Count);
                            foreach (TextTrack track in tracks)
                            {
                                bool isActiveTrack = (track == textTracks.GetActiveTextTrack());
                                GUI.color = isActiveTrack?Color.green:Color.white;
                                {
                                    if (GUILayout.Button(track.DisplayName))
                                    {
                                        if (isActiveTrack)
                                        {
                                            textTracks.SetActiveTextTrack(null);
                                        }
                                        else
                                        {
                                            textTracks.SetActiveTextTrack(track);
                                        }
                                    }
                                }
                            }
                            GUI.color = Color.white;

                            if (textTracks.GetActiveTextTrack() != null)
                            {
                                string text = string.Empty;
                                if (textTracks.GetCurrentTextCue() != null)
                                {
                                    text = textTracks.GetCurrentTextCue().Text;
                                    // Clip the text if it is too long
                                    if (text.Length >= 96)
                                    {
                                        text = string.Format("{0}...({1} chars)", text.Substring(0, 96), text.Length);
                                    }
                                }
                                GUILayout.Label(text, EditorHelper.IMGUI.GetWordWrappedTextAreaStyle(), GUILayout.Height(48f));
                            }

                            EditorGUILayout.Space();
                        }
                    }
                }
            }
            else
            {
                GUILayout.Label("No media loaded");
            }
        }
Example #6
0
        /// <summary>
        /// Null-safe method for testing if the first video track meets certain criteria.
        /// </summary>
        /// <param name="delegate">Does NOT need to check if the video track is null.  It will not be invoked if there are no video tracks.</param>
        /// <returns>The delegate's return value if this playlist has a video track; otherwise false.</returns>
        bool TestFirstVideoTrack(FirstVideoTrackDelegate @delegate)
        {
            var video = VideoTracks.FirstOrDefault();

            return(video != null && @delegate(video));
        }
Example #7
0
        public virtual void SelectTracks(int resolution, string codec, bool engOnly)
        {
            VideoTracks            = VideoTracks.GroupBy(x => x.Id).Select(x => x.First()).OrderBy(x => x.Bitrate).OrderBy(x => x.Height).ToList();
            AudioTracks            = AudioTracks.GroupBy(x => x.Id).Select(x => x.First()).OrderByDescending(x => x.Codec.Contains("dd")).OrderByDescending(x => x.Codec.Contains("ddp")).OrderByDescending(x => x.Codec.Contains("atmos")).OrderBy(x => x.Bitrate).ToList();
            SelectedSubtitleTracks = SelectedSubtitleTracks.GroupBy(x => x.Id).Select(x => x.First()).OrderBy(x => x.Name).ThenByDescending(x => x.LanguageCode.Contains("en")).ToList();

            List <VideoTrack> videoTrackPool = VideoTracks;
            List <AudioTrack> audioTrackPool = AudioTracks;

            /*if (DeviceConfig.L1Available)
             * {
             *  videoTrackPool = VideoTracks.Where(x => x.SecurityLevel != ITrack.SecurityLevel.Hardware).ToList();
             *  audioTrackPool = AudioTracks.Where(x => x.SecurityLevel != ITrack.SecurityLevel.Hardware).ToList();
             * }*/

            if (codec != null)
            {
                if (codec == "H264")
                {
                    videoTrackPool = videoTrackPool.Where(x => x.Codec.Contains("avc")).ToList();
                }
                else if (codec == "H265")
                {
                    videoTrackPool = videoTrackPool.Where(x => x.Codec.Contains("hvc") || x.Codec.Contains("hev")).ToList();
                }
            }

            if (resolution == 0)
            {
                SelectedVideoTracks.Add(videoTrackPool.Last());
            }
            else
            {
                try
                {
                    SelectedVideoTracks.Add(videoTrackPool.Where(x => x.Height == resolution).Last());
                }
                catch
                {
                    SelectedVideoTracks.Add(videoTrackPool.Last());
                }
            }

            string origLang = "en";

            foreach (var track in AudioTracks)
            {
                if (track.Name.Contains("Original"))
                {
                    origLang = track.Language;
                    break;
                }
            }

            SelectedAudioTracks = audioTrackPool.GroupBy(x => x.Language + x.Name.Contains("Description").ToString()).Select(x => x.OrderByDescending(y => y.Name.Contains("Description")).OrderByDescending(y => y.Bitrate).FirstOrDefault()).ToList();
            SelectedAudioTracks.AddRange(audioTrackPool.Where(x => x.Name.Contains("Description")).GroupBy(x => x.Language).Select(x => x.OrderByDescending(y => y.Name.Contains("Description")).OrderByDescending(y => y.Bitrate).FirstOrDefault()));
            SelectedAudioTracks = SelectedAudioTracks.OrderByDescending(y => y.Channels).OrderByDescending(y => y.Bitrate).OrderBy(x => x.Language).OrderByDescending(x => x.Language.Contains("en")).OrderByDescending(x => x.Language.Contains("en-us")).OrderByDescending(x => x.Language == origLang).ToList();

            SelectedSubtitleTracks = SelectedSubtitleTracks.OrderBy(x => x.LanguageCode).OrderByDescending(x => x.LanguageCode == origLang).OrderByDescending(x => x.LanguageCode.Contains("en")).Where(x => !x.Name.Contains("Forced")).ToList();

            if (engOnly)
            {
                SelectedAudioTracks = SelectedAudioTracks.Where(x => (x.Language.Contains("en") || x.Language == origLang) && !x.Name.Contains("Description")).ToList();
            }
            if (engOnly)
            {
                SelectedSubtitleTracks = new List <SubtitleTrack>()
                {
                    SelectedSubtitleTracks.Where(x => x.LanguageCode.Contains("en") || x.LanguageCode == origLang).FirstOrDefault()
                }
            }
            ;

            SelectedAudioTracks    = SelectedAudioTracks.Distinct().ToList();
            SelectedSubtitleTracks = SelectedSubtitleTracks.Distinct().ToList();

            /*
             * foreach (var subtitleTrack in SelectedSubtitleTracks)
             * {
             *  if (subtitleTrack.LanguageCode == origLang)
             *  {
             *      subtitleTrack.Default = true;
             *      break;
             *  }
             * }
             */
        }
Example #8
0
        public DASHPlaylist(string[] playlistUrls, bool[] playlistsAudioOnly, List <AudioTrackMetadata> audioMetadata = null)
        {
            foreach ((string playlistUrl, bool audioOnly) in playlistUrls.Zip(playlistsAudioOnly))
            {
                string originalPlaylist = Requests.Request(playlistUrl, null);

                XmlDocument xmlDoc = new XmlDocument();

                try
                {
                    xmlDoc.LoadXml(originalPlaylist);
                    OriginalPlaylists.Add(originalPlaylist);
                }
                catch
                {
                    continue;
                }

                string baseUrl = playlistUrl.Substring(0, playlistUrl.LastIndexOf("/") + 1);

                Dictionary <string, string> initDataPairs = new Dictionary <string, string>();

                foreach (XmlElement adaptationSet in xmlDoc["MPD"]["Period"].GetElementsByTagName("AdaptationSet"))
                {
                    try
                    {
                        string keyId;
                        try
                        {
                            keyId = adaptationSet.GetElementsByTagName("ContentProtection").Cast <XmlElement>().Where(x => x.HasAttribute("cenc:default_KID")).FirstOrDefault().GetAttribute("cenc:default_KID");
                        }
                        catch
                        {
                            keyId = adaptationSet.GetElementsByTagName("ContentProtection").Cast <XmlElement>().Where(x => x.HasAttribute("_:default_KID")).FirstOrDefault().GetAttribute("_:default_KID");
                        }
                        string initData = adaptationSet.GetElementsByTagName("ContentProtection").Cast <XmlElement>().Where(x => x.GetAttribute("schemeIdUri").ToLower().Contains("edef8ba9-79d6-4ace-a3c8-27dcd51d21ed")).FirstOrDefault().FirstChild.InnerText;
                        if (!initDataPairs.ContainsKey(keyId))
                        {
                            initDataPairs.Add(keyId, initData);
                        }
                    }
                    catch { }
                }

                foreach (XmlElement adaptationSet in xmlDoc["MPD"]["Period"].GetElementsByTagName("AdaptationSet"))
                {
                    bool   isEncrypted = false;
                    string initDataB64 = null;

                    XmlNodeList contentProtectionElements = adaptationSet.GetElementsByTagName("ContentProtection");

                    if (contentProtectionElements.Count > 0)
                    {
                        isEncrypted = true;
                        string keyId;
                        try
                        {
                            keyId = contentProtectionElements.Cast <XmlElement>().Where(x => x.HasAttribute("cenc:default_KID")).FirstOrDefault().GetAttribute("cenc:default_KID");
                        }
                        catch
                        {
                            keyId = contentProtectionElements.Cast <XmlElement>().Where(x => x.HasAttribute("_:default_KID")).FirstOrDefault().GetAttribute("_:default_KID");
                        }
                        initDataB64 = initDataPairs[keyId];
                    }

                    foreach (XmlElement representation in adaptationSet.GetElementsByTagName("Representation"))
                    {
                        string url = representation.GetElementsByTagName("BaseURL")[0].InnerText;

                        if (!url.Contains("https://") && !url.Contains("http://"))
                        {
                            url = baseUrl + url;
                        }

                        if (url.StartsWith("http:"))
                        {
                            url = url.Replace("http:", "https:");
                        }

                        if (adaptationSet.GetAttribute("contentType").ToLower() == "audio" || adaptationSet.GetAttribute("mimeType").ToLower().Contains("audio"))
                        {
                            string name = null;
                            if (adaptationSet.HasAttribute("label"))
                            {
                                name = adaptationSet.GetAttribute("label");
                            }

                            string codec = null;

                            if (representation.HasAttribute("codecs"))
                            {
                                codec = representation.GetAttribute("codecs");
                            }
                            else
                            {
                                codec = adaptationSet.GetAttribute("codecs");
                            }

                            int channels = 2;

                            try
                            {
                                XmlElement audioChannelConfiguration = null;

                                try
                                {
                                    audioChannelConfiguration = representation.GetElementsByTagName("AudioChannelConfiguration").Cast <XmlElement>().FirstOrDefault();
                                }
                                catch
                                {
                                    audioChannelConfiguration = adaptationSet.GetElementsByTagName("AudioChannelConfiguration").Cast <XmlElement>().FirstOrDefault();
                                }

                                if (audioChannelConfiguration == null)
                                {
                                    audioChannelConfiguration = adaptationSet.GetElementsByTagName("AudioChannelConfiguration").Cast <XmlElement>().FirstOrDefault();
                                }

                                string channelValue = audioChannelConfiguration.GetAttribute("value");

                                if (channelValue == "2")
                                {
                                    channels = 2;
                                }
                                else if (channelValue == "A000")
                                {
                                    channels = 2;
                                }
                                else if (channelValue == "F801" || channelValue == "6")
                                {
                                    channels = 6;
                                }
                                else if (channelValue == "FA01" || channelValue == "8")
                                {
                                    channels = 8;
                                }
                            }
                            catch
                            {
                                channels = 2;
                            }

                            int bandwidth = int.Parse(representation.GetAttribute("bandwidth"));

                            string id = representation.GetAttribute("id");
                            if (adaptationSet.HasAttribute("audioTrackId"))
                            {
                                id = adaptationSet.GetAttribute("audioTrackId") + "_" + id;
                            }

                            string lang;

                            try
                            {
                                //amzn
                                lang = id.Split("_")[0];
                            }
                            catch
                            {
                                lang = adaptationSet.GetAttribute("lang");
                            }

                            if (lang == null || lang == "")
                            {
                                lang = "en";
                            }

                            if (audioMetadata != null && audioMetadata.Count > 1 && adaptationSet.HasAttribute("audioTrackId"))
                            {
                                string trackId = adaptationSet.GetAttribute("audioTrackId");

                                name = audioMetadata.FirstOrDefault(x => x.AudioTrackId == trackId).DisplayName;
                            }
                            else if (audioMetadata != null && audioMetadata.Count == 1)
                            {
                                name = audioMetadata[0].DisplayName;
                            }

                            if (name == null)
                            {
                                name = lang;
                            }

                            var audioTrack = new AudioTrack
                            {
                                Encrypted     = isEncrypted,
                                Id            = id,
                                Name          = name,
                                InitDataB64   = initDataB64,
                                Urls          = new string[] { url },
                                Segments      = 1,
                                Codec         = codec,
                                Bitrate       = bandwidth,
                                Channels      = channels,
                                Language      = lang,
                                SecurityLevel = ITrack.SecurityLevel.Unknown
                            };

                            AudioTracks.Add(audioTrack);
                        }
                        else if ((adaptationSet.GetAttribute("contentType").ToLower() == "video" || adaptationSet.GetAttribute("mimeType").ToLower().Contains("video")) && !audioOnly)
                        {
                            string frameRate = "24000/1001";

                            if (representation.HasAttribute("frameRate"))
                            {
                                frameRate = representation.GetAttribute("frameRate");
                            }
                            else
                            {
                                frameRate = adaptationSet.GetAttribute("frameRate");
                            }

                            var frameRateValue = 0.0;
                            if (frameRate.Contains("/"))
                            {
                                frameRateValue = Utils.EvaluateEquation(frameRate);
                            }
                            else
                            {
                                frameRateValue = float.Parse(frameRate);
                            }

                            int bandwidth = int.Parse(representation.GetAttribute("bandwidth"));

                            try
                            {
                                bandwidth = int.Parse(representation.GetAttribute("id").Split("=")[1]);
                            }
                            catch { }

                            var videoTrack = new VideoTrack
                            {
                                Encrypted     = isEncrypted,
                                Id            = representation.GetAttribute("id"),
                                InitDataB64   = initDataB64,
                                Urls          = new string[] { url },
                                Segments      = 1,
                                Codec         = representation.GetAttribute("codecs"),
                                Bitrate       = bandwidth,
                                Width         = int.Parse(representation.GetAttribute("width")),
                                Height        = int.Parse(representation.GetAttribute("height")),
                                FrameRate     = frameRateValue,
                                SecurityLevel = ITrack.SecurityLevel.Unknown
                            };

                            VideoTracks.Add(videoTrack);
                        }
                    }
                }
            }
        }