Пример #1
0
 public PlaylistSegment CreateSegment(DateTime startTime, IPlayItem playItem)
 {
     return(new PlaylistSegment(startTime, playItem)
     {
         IsDirty = true
     });
 }
Пример #2
0
        /// <summary>
        /// 在指定的播出项之后添加一条顺播。
        /// </summary>
        /// <param name="prevItem"></param>
        /// <param name="newItem"></param>
        public void AddAuto(IPlayItem prevItem, IPlayItem newItem)
        {
            Debug.Assert(newItem.ScheduleMode == PlayScheduleMode.Auto);

            //if (_playlist.IsLocked(prevItem)) throw new PlayItemLockedException();

            var segment = FindSegment(prevItem);

            DateTime startTime, stopTime;
            int      beginIndex, endIndex;

            if (segment.Head == null)
            {
                startTime  = segment.StartTime;
                beginIndex = segment.BeginIndex;
            }
            else
            {
                startTime  = segment.Head.CalculatedStopTime;
                beginIndex = segment.BeginIndex + 1;
            }

            stopTime = segment.StopTime;
            endIndex = segment.EndIndex;

            this.Rebuild(startTime, stopTime, beginIndex, endIndex, (items) =>
            {
                // NOTE: FindIndex maybe -1 in case of prevItem is Timing
                var i = items.FindIndex(si => si.PlayItem == prevItem);
                items.Insert(i + 1, new ScheduleItem(newItem));
            });
        }
Пример #3
0
        /// <summary>
        /// 把指定的顺播下移一个位置。
        /// </summary>
        /// <param name="playItem"></param>
        public void MoveDown(IPlayItem playItem)
        {
            Debug.Assert(playItem.ScheduleMode == PlayScheduleMode.Auto);

            //if (_playlist.IsLocked(playItem)) throw new PlayItemLockedException();

            if (_playlist[_playlist.Count - 1] == playItem)
            {
                return;
            }

            //var index = _playlist.FindFirstIndex(i => i == playItem);
            var index = _playlist.FindIndex(i => i.PlayItem == playItem);

            if (index == -1)
            {
                throw new ArgumentException();
            }


            var newPrevItem = _playlist[index + 1];

            //Reorder(newPrevItem, playItem);
            Reorder(newPrevItem.PlayItem, playItem);
        }
        /// <summary>
        /// Set the current item for playing.
        /// </summary>
        /// <param name="index">Position in list</param>
        public void SetItem(int index)
        {
            lock (this.SyncRoot)
            {
                if (index < 0 || index >= _items.Count)
                {
                    return;
                }

                Stop();
                _currentItemIndex = index;
                IPlayItem item = _items[_currentItemIndex] as IPlayItem;
                try
                {
                    _engine.Play(item);
                }
                catch (IOException ex)
                {
                    log.Error("SetItem caught a IOException", ex);
                }
                catch (StreamNotFoundException)
                {
                    // let the engine retain the STOPPED state
                    // and wait for control from outside
                    log.Debug("SetItem caught a StreamNotFoundException");
                }
                catch (NotSupportedException ex)
                {
                    log.Error("Illegal state exception on playlist item setup", ex);
                }
            }
        }
Пример #5
0
        public void AddTimingItem(IPlayItem playItem)
        {
            //LogAction();
            Debug.Assert(playItem.PlaybillItem.ScheduleMode == PlayScheduleMode.Timing);

            ValidateTimeRange(playItem);

            if (_segments.IsEmpty)
            {
                if (_buildOption.RequireFirstTimingItem && playItem.StartTime != _buildOption.PlayTimeRange.StartTime)
                {
                    throw new ArgumentException($"第一个定时播开始时间必须是{_buildOption.PlayTimeRange.StartTime}");
                }

                if (playItem.StartTime != _buildOption.PlayTimeRange.StartTime)
                {
                    TimeSpan duration = _buildOption.PlayTimeRange.StartTime.Subtract(playItem.StartTime);
                    if (!ValidatePlayDuration(duration))
                    {
                        throw new InvalidOperationException("操作无效,该操作将产生播放时长小于最小播放时长的自动垫片");
                    }
                    _segments.AddLast(_segments.CreateSegment(_buildOption.PlayTimeRange.StartTime));
                }

                var segment = _segments.CreateSegment(playItem);
                _segments.AddLast(segment);
            }
            else
            {
                _segments.LastSegment.Add(playItem);
            }
        }
Пример #6
0
        /// <summary>
        /// 在列表末尾添加一个顺播。
        /// </summary>
        /// <param name="playItem"></param>
        public void AddAuto(IPlayItem playItem)
        {
            Debug.Assert(playItem.ScheduleMode == PlayScheduleMode.Auto);

            var      prevTuple = FindLastTiming(i => true);
            DateTime startTime, stopTime = DateTime.MaxValue;
            int      beginIndex, endIndex = _playlist.Count - 1;

            if (prevTuple.Item2 == -1)
            {
                if (_playlist.Count > 0)
                {
                    startTime  = _playlist[0].StartTime;
                    beginIndex = 0;
                }
                else
                {
                    var playlistStartTime = GetPlaylistStartTime();
                    if (playlistStartTime == null)
                    {
                        throw new InvalidOperationException("第一个播放项必须是定时播。");
                    }

                    startTime  = playlistStartTime.Value;
                    beginIndex = 0;
                }
            }
            else
            {
                startTime  = prevTuple.Item1.CalculatedStopTime;
                beginIndex = prevTuple.Item2 + 1;
            }

            Rebuild(startTime, stopTime, beginIndex, endIndex, (items) => items.Add(new ScheduleItem(playItem)));
        }
Пример #7
0
        public void AddAutoItem(IPlayItem playItem, IPlayItem prevItem)
        {
            Debug.Assert(playItem.PlaybillItem.ScheduleMode == PlayScheduleMode.Auto);

            if (_segments.IsEmpty)
            {
                if (_buildOption.RequireFirstTimingItem)
                {
                    throw new InvalidOperationException("第一个播放项必须是定时播。");
                }

                var newSegment = _segments.CreateSegment(_buildOption.PlayTimeRange.StartTime, playItem);
                _segments.AddLast(newSegment);
            }
            else
            {
                PlaylistSegment segment = prevItem != null?
                                          _segments.FindLastSegment((s) => s.Contains(prevItem)) : _segments.LastSegment;

                if (segment == null)
                {
                    throw new ArgumentException();
                }

                if (prevItem == null)
                {
                    segment.Add(playItem);
                }
                else
                {
                    segment.InsertAuto(playItem, prevItem);
                }
            }
        }
Пример #8
0
        public void AddTimingBreakItem(IPlayItem playItem)
        {
            Debug.Assert(playItem.PlaybillItem.ScheduleMode == PlayScheduleMode.TimingBreak);

            ValidateTimeRange(playItem);

            if (_segments.IsEmpty)
            {
                if (_buildOption.RequireFirstTimingItem)
                {
                    throw new InvalidOperationException("第一个播放项必须是定时播。");
                }

                var newSegment = _segments.CreateSegment(_buildOption.PlayTimeRange.StartTime, playItem);
                _segments.AddLast(newSegment);
            }
            else
            {
                var segment = _segments.FindLastSegment((s) => s.StartTime <= playItem.StartTime);
                if (segment == null)
                {
                    throw new ArgumentException();
                }

                segment.Add(playItem);
            }
        }
 public void AddItem(IPlayItem item, int index)
 {
     lock (this.SyncRoot)
     {
         _items.Insert(index, item);
     }
 }
 public void AddItem(IPlayItem item)
 {
     lock (this.SyncRoot)
     {
         _items.Add(item);
     }
 }
Пример #11
0
 public PlaylistSegment CreateSegment(IPlayItem playItem)
 {
     return(new PlaylistSegment(playItem)
     {
         IsDirty = true
     });
 }
Пример #12
0
        // case1: 当mediaSource为null,newPlayRange不为null时只改变入出点。
        // case2: 当mediaSource不为null,newPlayRange为null时等长替换媒体源。
        // case3: 当mediaSource不为null,newPlayRange不为null时变长替换媒体源。
        private void ChangeMediaSourceInternal(IPlayItem playItem, IMediaSource mediaSource, PlayRange?newPlayRange)
        {
            //if (_playlist.IsLocked(playItem)) throw new PlayItemLockedException();


            if (mediaSource == null && newPlayRange == null)
            {
                return;
            }
            if (mediaSource == null && newPlayRange.Value == playItem.PlayRange)
            {
                return;
            }

            if (newPlayRange != null && (playItem.ScheduleMode == PlayScheduleMode.Timing || playItem.ScheduleMode == PlayScheduleMode.TimingBreak))
            {
                //_playlist.ValidateTimeRange(playItem.StartTime, newPlayRange.Value.Duration, playItem);
                ValidateTimeRange(playItem.StartTime, newPlayRange.Value.Duration, playItem);
            }

            PlayRange playRange = newPlayRange ?? new PlayRange(TimeSpan.Zero, playItem.CalculatedPlayDuration /*playItem.PlayRange.Duration*/);

            if (mediaSource == null)
            {
                mediaSource = playItem.MediaSource; //.Clone();
            }

            var newPlaySource = new PlaySource(mediaSource, playRange, playItem.CGItems);

            IPlayItem newPlayItem = null;

            switch (playItem.ScheduleMode)
            {
            case PlayScheduleMode.Timing:
                newPlayItem = (IPlayItem)PlaybillItem.Timing(newPlaySource, playItem.StartTime);
                break;

            case PlayScheduleMode.TimingBreak:
                newPlayItem = (IPlayItem)PlaybillItem.TimingBreak(newPlaySource, playItem.StartTime);
                break;

            case PlayScheduleMode.Auto:
                newPlayItem = new AutoPlayItem(PlaybillItem.Auto(newPlaySource));
                break;
            }

            var segment = this.FindSegment(playItem);

            DateTime startTime  = segment.StartTime;
            int      beginIndex = segment.BeginIndex;

            DateTime stopTime = segment.StopTime;
            int      endIndex = segment.EndIndex;

            Rebuild(startTime, stopTime, beginIndex, endIndex, (items) =>
            {
                var i    = items.FindIndex(si => si.PlayItem == playItem);
                items[i] = new ScheduleItem(newPlayItem);
            });
        }
Пример #13
0
        //locked
        //[MethodImpl(MethodImplOptions.Synchronized)]
        private void ItemPlayStart()
        {
            //IPlayItem playItem;
            FileNameAndDemo playMedia = m_MediaQueue.Peek();
            string          extension = Path.GetExtension(playMedia.FileName);

            Debug.Assert(extension.Length > 0);
            _Media media = m_IMediaManager.GetMedia(extension);

            //IMPORTANT DirectXException Handling
            switch (media.MediaType)
            {
            case MediaTypes.Audio:
                m_PlayItem = new AudioPlayItem(playMedia.FileName, playMedia.Demo);
                break;

            case MediaTypes.Video:
                m_PlayItem = new VideoPlayItem(playMedia.FileName, playMedia.Demo);
                break;

            case MediaTypes.Karaoke:
                m_PlayItem = new KarPlayItem(playMedia.FileName, playMedia.Demo);
                break;
            }

            /*MediaItemInfo tempItemInfo;
             * Program.TryGetPlayItemInfoByExtension(
             *  Path.GetExtension(playMedia.FullName).ToLower(), out tempItemInfo);*/
            //_Media media;
            //MediaManager.Instance.TryGetMedia(playMedia.FileName, out media);
            m_PlayItem.Volume = m_PlayItem.IsDemo ? media.DemoVolume : media.OrderVolume;
            m_PlayItem.Play();
        }
Пример #14
0
        public bool CanEdit(IPlayItem playItem, EditOption option, object context = null)
        {
            switch (option)
            {
            case EditOption.Duration:
                return(!playItem.IsAutoPadding() && (playItem.MediaSource is IChannelMediaSource));

            case EditOption.StartTime:
                return(playItem.ScheduleMode == PlayScheduleMode.Timing || playItem.ScheduleMode == PlayScheduleMode.TimingBreak);

            case EditOption.SourceAndPlayRange:
                return(true);

            case EditOption.SourceOnly:
                PlayRange newRange = (PlayRange)context;
                return(newRange.Duration >= playItem.CalculatedPlayDuration);

            case EditOption.ScheduleMode:
                PlayScheduleMode newMode = (PlayScheduleMode)context;
                return((newMode != playItem.ScheduleMode) && (newMode == PlayScheduleMode.Auto || !playItem.IsAutoPadding()));

            case EditOption.Move:
                return(!playItem.IsAutoPadding() && playItem.ScheduleMode == PlayScheduleMode.Auto);
            }

            return(false);
        }
Пример #15
0
 public ScheduleItem(IPlayItem playItem)
 {
     _isDirty   = false;
     _playItem  = playItem;
     _startTime = _playItem.StartTime;
     _calculatedPlayDuration = _playItem.PlaybillItem.PlayRange.Duration; //  _playItem.CalculatedPlayDuration;
 }
Пример #16
0
        public void ForcePlay(IPlayItem currentItem, IPlayItem forcedItem)
        {
            this.Delete(forcedItem);

            DateTime stopTime;
            int      beginIndex;

            var startTime    = DateTime.Now.AddSeconds(1.0);
            var currentIndex = _playlist.FindIndex(i => i.PlayItem == currentItem);

            beginIndex = currentIndex + 1;

            Tuple <ScheduleItem, int> temp = FindFirstTiming(beginIndex, (i) => true);
            int endIndex;

            if (temp.Item1 != null)
            {
                stopTime = temp.Item1.StartTime;
                endIndex = temp.Item2 - 1;
            }
            else
            {
                stopTime = DateTime.MaxValue;
                endIndex = _playlist.Count - 1;
            }

            // 调整当前项的播放时长(入出点)


            // 复制当前项,并调整时长。
            var startOffset = startTime.Subtract(currentItem.StartTime);

            var newRange = new PlayRange(currentItem.CalculatedPlayRange.StartPosition + startOffset,
                                         currentItem.CalculatedPlayRange.Duration - startOffset);
            var copyItem = new AutoPlayItem(new AutoPlaybillItem(currentItem.PlaybillItem.PlaySource.Clone(newRange)));



            //if (segment.Head == null)
            //{
            //    startTime = segment.StartTime;
            //    beginIndex = segment.BeginIndex;
            //}
            //else
            //{
            //    startTime = segment.Head.CalculatedStopTime;
            //    beginIndex = segment.BeginIndex + 1;
            //}

            //stopTime = segment.StopTime;
            //endIndex = segment.EndIndex;

            this.Rebuild(startTime, stopTime, beginIndex, endIndex, (items) =>
            {
                // 插入复制项和forcedItem。
                items.Insert(0, new ScheduleItem(copyItem));
                items.Insert(0, new ScheduleItem(forcedItem));
            });
        }
Пример #17
0
        internal void Split(TimeSpan duration, out ScheduleItem first, out ScheduleItem second)
        {
            IPlayItem firstItem = null, secondItem = null;

            _playItem.Split(duration, out firstItem, out secondItem);
            first  = new ScheduleItem(firstItem);
            second = new ScheduleItem(secondItem);
        }
Пример #18
0
 private void AddNewTimingBreakItem(IPlayItem playItem)
 {
     if (_newTimingBreakItems == null)
     {
         _newTimingBreakItems = new SortedList <DateTime, IPlayItem>();
     }
     _newTimingBreakItems.Add(playItem.StartTime, playItem);
 }
Пример #19
0
 public void PlayQueued(IPlayItem playItem)
 {
     lock (_lockObj)
     {
         RemoveSameEvents(playItem.EventCode);
         _playList.AddLast(playItem);
     }
 }
Пример #20
0
 private static PlayItemAddContext CreateContext(IPlayItem playItem, PlayScheduleMode scheduleMode)
 {
     return(new PlayItemAddContext
     {
         PlayItem = playItem,
         ScheduleMode = scheduleMode
     });
 }
Пример #21
0
 private void PlayQueued(AudioDeviceMgr mgr, IPlayItem playItem)
 {
     if (GameRunning)
     {
         mgr.PlayQueued(playItem);
         OnPlayRequest?.Invoke();
     }
 }
Пример #22
0
 public void PlayNow(IPlayItem playItem)
 {
     lock (_lockObj)
     {
         _playList.Clear();
         _device.Stop();
         _playList.AddLast(playItem);
     }
 }
Пример #23
0
        public void Split(TimeSpan duration, out IPlayItem first, out IPlayItem second)
        {
            PlayRange firstRange, secondRange;

            FCSPlayout.Domain.PlayRange.Split(this.PlayRange, duration, out firstRange, out secondRange);

            first  = new AutoPlayItem(this.PlaybillItem.Clone(firstRange), firstRange);
            second = new AutoPlayItem(this.PlaybillItem.Clone(secondRange), secondRange);
        }
Пример #24
0
        internal BindablePlayItem CreateBindablePlayItem(IPlayItem playItem)
        {
            string filePath = null;

            if (playItem.MediaSource.Category == MediaSourceCategory.File)
            {
                filePath = _filePathResolver.Resolve(((AppInfrastructure.FileMediaSource)playItem.MediaSource).FileName);
            }
            return(new BindablePlayItem(playItem, filePath, _itemEditFactory));
        }
Пример #25
0
        public static bool IsAutoPadding(this IPlayItem playItem)
        {
            var autoItem = playItem as AutoPlayItem;

            if (autoItem != null)
            {
                return(autoItem.IsAutoPadding);
            }
            return(false);
        }
Пример #26
0
 /// <summary>
 /// Set the current item for playing.
 /// </summary>
 /// <param name="index">Position in list</param>
 public void SetItem(int index)
 {
     lock (this.SyncRoot)
     {
         if (index < 0 || index >= _items.Count)
             return;
         Stop();
         _currentItemIndex = index;
         IPlayItem item = _items[_currentItemIndex] as IPlayItem;
         Play(item);
     }
 }
Пример #27
0
 /// <summary>
 /// Go for next item decided by controller logic.
 /// </summary>
 public void NextItem()
 {
     lock (this.SyncRoot)
     {
         Stop();
         MoveToNext();
         if (_currentItemIndex == -1)
             return;
         IPlayItem item = _items[_currentItemIndex] as IPlayItem;
         Play(item);
     }
 }
Пример #28
0
        internal void InsertAuto(IPlayItem playItem, IPlayItem prevItem)
        {
            int index = _playItems.IndexOf(prevItem);

            if (index < 0)
            {
                throw new InvalidOperationException();
            }

            _playItems.Insert(index + 1, playItem);
            this.IsDirty = true;
        }
Пример #29
0
        /// <summary>
        /// Notifies subscribers on item stop
        /// </summary>
        /// <param name="item">Item that just has been stopped.</param>
        internal void NotifyItemStop(IPlayItem item)
        {
            IStreamAwareScopeHandler handler = GetStreamAwareHandler();

            if (handler != null)
            {
                try {
                    handler.StreamPlaylistItemStop(this, item);
                } catch (Exception ex) {
                    log.Error("Error notify streamPlaylistItemStop", ex);
                }
            }
        }
Пример #30
0
        /// <summary>
        /// Notify on item seek
        /// </summary>
        /// <param name="item">Playlist item.</param>
        /// <param name="position">Seek position.</param>
        internal void NotifyItemSeek(IPlayItem item, int position)
        {
            IStreamAwareScopeHandler handler = GetStreamAwareHandler();

            if (handler != null)
            {
                try {
                    handler.StreamPlaylistVODItemSeek(this, item, position);
                } catch (Exception ex) {
                    log.Error("Error notify streamPlaylistVODItemSeek", ex);
                }
            }
        }
Пример #31
0
		public void AddItem(IPlayItem item) {
			lock (this.SyncRoot) {
				_items.Add(item);
			}
		}
Пример #32
0
        /// <summary>
        /// Play stream
        /// </summary>
        /// <param name="item">Playlist item.</param>
        /// <param name="withReset">Send reset status before playing.</param>
        public void Play(IPlayItem item, bool withReset)
        {
            lock (this.SyncRoot)
            {
                // Can't play if state is not stopped
                if (_playlistSubscriberStream.State != State.STOPPED)
                    throw new IllegalStateException();
                if (_msgIn != null)
                {
                    _msgIn.Unsubscribe(this);
                    _msgIn = null;
                }
                // Play type determination
                // http://livedocs.adobe.com/flex/3/langref/flash/net/NetStream.html#play%28%29
                // The start time, in seconds. Allowed values are -2, -1, 0, or a positive number. 
                // The default value is -2, which looks for a live stream, then a recorded stream, 
                // and if it finds neither, opens a live stream. 
                // If -1, plays only a live stream. 
                // If 0 or a positive number, plays a recorded stream, beginning start seconds in.
                //
                // -2: live then recorded, -1: live, >=0: recorded
                int type = (int)(item.Start / 1000);
                // see if it's a published stream
                IScope thisScope = _playlistSubscriberStream.Scope;
                string itemName = item.Name;
                //check for input and type
                InputType sourceType = _providerService.LookupProviderInputType(thisScope, itemName);

                bool isPublishedStream = sourceType == InputType.Live;
                bool isFileStream = sourceType == InputType.Vod;
                bool sendNotifications = true;

                // decision: 0 for Live, 1 for File, 2 for Wait, 3 for N/A
                switch (type)
                {
                    case -2:
                        if (isPublishedStream)
                            _playDecision = 0;
                        else if (isFileStream)
                            _playDecision = 1;
                        else
                            _playDecision = 2;
                        break;
                    case -1:
                        if (isPublishedStream)
                            _playDecision = 0;
                        else
                            _playDecision = 2;
                        break;
                    default:
                        if (isFileStream)
                            _playDecision = 1;
                        break;
                }
                if (log.IsDebugEnabled)
                    log.Debug(string.Format("Play decision is {0} (0=Live, 1=File, 2=Wait, 3=N/A)", _playDecision));
                _currentItem = item;
                long itemLength = item.Length;
                switch (_playDecision)
                {
                    case 0:
                        //get source input without create
                        _msgIn = _providerService.GetLiveProviderInput(thisScope, itemName, false);
                        // Drop all frames up to the next keyframe
                        _videoFrameDropper.Reset(FrameDropperState.SEND_KEYFRAMES_CHECK);
                        if (_msgIn is IBroadcastScope)
                        {
                            // Send initial keyframe
                            IClientBroadcastStream stream = (_msgIn as IBroadcastScope).GetAttribute(Constants.BroadcastScopeStreamAttribute) as IClientBroadcastStream;
                            if (stream != null && stream.CodecInfo != null)
                            {
                                IVideoStreamCodec videoCodec = stream.CodecInfo.VideoCodec;
                                if (videoCodec != null)
                                {
                                    if (withReset)
                                    {
                                        SendReset();
                                        SendResetStatus(item);
                                        SendStartStatus(item);
                                    }
                                    sendNotifications = false;
                                    //send decoder configuration if it exists
                                    ByteBuffer config = videoCodec.GetDecoderConfiguration();
                                    if (config != null)
                                    {
                                        VideoData conf = new VideoData(config);
                                        try
                                        {
                                            conf.Timestamp = 0;
                                            RtmpMessage confMsg = new RtmpMessage();
                                            confMsg.body = conf;
                                            _msgOut.PushMessage(confMsg);
                                        }
                                        finally
                                        {
                                            //conf.release();
                                        }
                                    }
                                    //Check for a keyframe to send
                                    ByteBuffer keyFrame = videoCodec.GetKeyframe();
                                    if (keyFrame != null)
                                    {
                                        VideoData video = new VideoData(keyFrame);
                                        try
                                        {
                                            video.Timestamp = 0;
                                            RtmpMessage videoMsg = new RtmpMessage();
                                            videoMsg.body = video;
                                            _msgOut.PushMessage(videoMsg);
                                            // Don't wait for keyframe
                                            _videoFrameDropper.Reset();
                                        }
                                        finally
                                        {
                                            //video.release();
                                        }
                                    }
                                }
                            }
                        }
                        _msgIn.Subscribe(this, null);
                        break;
                    case 2:
                        //get source input with create
                        _msgIn = _providerService.GetLiveProviderInput(thisScope, itemName, true);
                        _msgIn.Subscribe(this, null);
                        _waiting = true;
                        if (type == -1 && itemLength >= 0)
                        {
                            //log.debug("Creating wait job");
                            // Wait given timeout for stream to be published
                            PlaylistSubscriberStreamJob1 job = new PlaylistSubscriberStreamJob1(this, itemName);
                            _waitLiveJob = _schedulingService.AddScheduledOnceJob(item.Length, job);
                        }
                        else if (type == -2)
                        {
                            //log.debug("Creating wait job");
                            // Wait x seconds for the stream to be published
                            PlaylistSubscriberStreamJob2 job = new PlaylistSubscriberStreamJob2(this, itemName);
                            _waitLiveJob = _schedulingService.AddScheduledOnceJob(15000, job);
                        }
                        else
                        {
                            ConnectToProvider(itemName);
                        }
                        break;
                    case 1:
                        _msgIn = _providerService.GetVODProviderInput(thisScope, itemName);
                        if (_msgIn == null)
                        {
                            SendStreamNotFoundStatus(_currentItem);
                            throw new StreamNotFoundException(itemName);
                        }
                        if (!_msgIn.Subscribe(this, null))
                        {
                            log.Error("Input source subscribe failed");
                        }
                        break;
                    default:
                        SendStreamNotFoundStatus(_currentItem);
                        throw new StreamNotFoundException(itemName);
                }
                _playlistSubscriberStream.State = State.PLAYING;
                IMessage msg = null;
                _streamOffset = 0;
                _streamStartTS = -1;
                if (_playDecision == 1)
                {
                    if (withReset)
                    {
                        ReleasePendingMessage();
                    }
                    SendVODInitCM(_msgIn, item);
                    // Don't use pullAndPush to detect IOExceptions prior to sending NetStream.Play.Start
                    if (item.Start > 0)
                    {
                        _streamOffset = SendVODSeekCM(_msgIn, (int)item.Start);
                        // We seeked to the nearest keyframe so use real timestamp now
                        if (_streamOffset == -1)
                        {
                            _streamOffset = (int)item.Start;
                        }
                    }
                    msg = _msgIn.PullMessage();
                    if (msg is RtmpMessage)
                    {
                        IRtmpEvent body = ((RtmpMessage)msg).body;
                        if (itemLength == 0)
                        {
                            // Only send first video frame
                            body = ((RtmpMessage)msg).body;
                            while (body != null && !(body is VideoData))
                            {
                                msg = _msgIn.PullMessage();
                                if (msg == null)
                                    break;
                                if (msg is RtmpMessage)
                                    body = ((RtmpMessage)msg).body;
                            }
                        }
                        if (body != null)
                        {
                            // Adjust timestamp when playing lists
                            body.Timestamp = body.Timestamp + _timestampOffset;
                        }
                    }
                }
                if (sendNotifications)
                {
                    if (withReset)
                    {
                        SendReset();
                        SendResetStatus(item);
                    }
                    SendStartStatus(item);
                    if (!withReset)
                    {
                        SendSwitchStatus();
                    }
                }
                if (msg != null)
                {
                    SendMessage((RtmpMessage)msg);
                }
                _playlistSubscriberStream.NotifyItemPlay(_currentItem, !_isPullMode);
                if (withReset)
                {
                    long currentTime = System.Environment.TickCount;
                    _playbackStart = currentTime - _streamOffset;
                    _nextCheckBufferUnderrun = currentTime + _bufferCheckInterval;
                    if (_currentItem.Length != 0)
                    {
                        EnsurePullAndPushRunning();
                    }
                }
            }
        }
Пример #33
0
 /// <summary>
 /// Play stream.
 /// </summary>
 /// <param name="item">Playlist item.</param>
 public void Play(IPlayItem item)
 {
     Play(item, true);
 }
Пример #34
0
 /// <summary>
 /// Send VOD init control message
 /// </summary>
 /// <param name="msgIn"></param>
 /// <param name="item"></param>
 private void SendVODInitCM(IMessageInput msgIn, IPlayItem item)
 {
     OOBControlMessage oobCtrlMsg = new OOBControlMessage();
     oobCtrlMsg.Target = typeof(IPassive).Name;
     oobCtrlMsg.ServiceName = "init";
     oobCtrlMsg.ServiceParameterMap.Add("startTS", item.Start);
     _msgIn.SendOOBControlMessage(this, oobCtrlMsg);
 }
Пример #35
0
 /// <summary>
 /// Play a specific IPlayItem.
 /// The strategy for now is VOD first, Live second.
 /// </summary>
 /// <param name="item">Item to play</param>
 protected void Play(IPlayItem item)
 {
     // Return if already playing
     if (_state != State.STOPPED)
         return;
     // Assume this is not live stream
     bool isLive = false;
     IProviderService providerService = ScopeUtils.GetScopeService(this.Scope, typeof(IProviderService)) as IProviderService;
     _msgIn = providerService.GetVODProviderInput(this.Scope, item.Name);
     if (_msgIn == null)
     {
         _msgIn = providerService.GetLiveProviderInput(this.Scope, item.Name, true);
         isLive = true;
     }
     if (_msgIn == null)
     {
         log.Warn("Can't get both VOD and Live input from providerService");
         return;
     }
     _state = State.PLAYING;
     _currentItem = item;
     SendResetMessage();
     _msgIn.Subscribe(this, null);
     if (isLive)
     {
         if (item.Length >= 0)
         {
             PlayItemScheduledJob job = new PlayItemScheduledJob(this);
             _liveJobName = _schedulingService.AddScheduledOnceJob(item.Length, job);
         }
     }
     else
     {
         long start = item.Start;
         if (start < 0)
             start = 0;
         SendVODInitCM(_msgIn, (int)start);
         StartBroadcastVOD();
     }
 }
Пример #36
0
        /// <summary>
        /// Send unpublished status notification
        /// </summary>
        /// <param name="item"></param>
        private void SendUnpublishedStatus(IPlayItem item)
        {
            StatusASO unpublished = new StatusASO(StatusASO.NS_PLAY_UNPUBLISHNOTIFY);
            unpublished.clientid = this.StreamId;
            unpublished.details = item.Name;

            StatusMessage unpublishedMsg = new StatusMessage();
            unpublishedMsg.body = unpublished;
            DoPushMessage(unpublishedMsg);
        }
Пример #37
0
        /// <summary>
        /// Send resume status notification
        /// </summary>
        /// <param name="item"></param>
        private void SendResumeStatus(IPlayItem item)
        {
            StatusASO resume = new StatusASO(StatusASO.NS_UNPAUSE_NOTIFY);
            resume.clientid = this.StreamId;
            resume.details = item.Name;

            StatusMessage resumeMsg = new StatusMessage();
            resumeMsg.body = resume;
            DoPushMessage(resumeMsg);
        }
Пример #38
0
        /// <summary>
        /// Send pause status notification
        /// </summary>
        /// <param name="item"></param>
        private void SendPauseStatus(IPlayItem item)
        {
            StatusASO pause = new StatusASO(StatusASO.NS_PAUSE_NOTIFY);
            pause.clientid = this.StreamId;
            pause.details = item.Name;

            StatusMessage pauseMsg = new StatusMessage();
            pauseMsg.body = pause;
            DoPushMessage(pauseMsg);
        }
Пример #39
0
		/// <summary>
		/// Notify on item seek
		/// </summary>
		/// <param name="item">Playlist item.</param>
		/// <param name="position">Seek position.</param>
		internal void NotifyItemSeek(IPlayItem item, int position) {
			IStreamAwareScopeHandler handler = GetStreamAwareHandler();
			if (handler != null) {
				try {
					handler.StreamPlaylistVODItemSeek(this, item, position);
				} catch (Exception ex) {
					log.Error("Error notify streamPlaylistVODItemSeek", ex);
				}
			}
		}
Пример #40
0
        /// <summary>
        /// Send playback stoppage status notification
        /// </summary>
        /// <param name="item"></param>
        private void SendStopStatus(IPlayItem item)
        {
            StatusASO stop = new StatusASO(StatusASO.NS_PLAY_STOP);
            stop.clientid = this.StreamId;
            stop.description = "Stopped playing " + item.Name + ".";
            stop.details = item.Name;

            StatusMessage stopMsg = new StatusMessage();
            stopMsg.body = stop;
            DoPushMessage(stopMsg);
        }
Пример #41
0
        /// <summary>
        /// Send playback start status notification
        /// </summary>
        /// <param name="item"></param>
        private void SendStartStatus(IPlayItem item)
        {
            StatusASO start = new StatusASO(StatusASO.NS_PLAY_START);
            start.clientid = this.StreamId;
            start.details = item.Name;
            start.description = "Started playing " + item.Name + '.';

            StatusMessage startMsg = new StatusMessage();
            startMsg.body = start;
            DoPushMessage(startMsg);
        }
Пример #42
0
 /// <summary>
 /// Send reset status for item
 /// </summary>
 /// <param name="item"></param>
 private void SendResetStatus(IPlayItem item)
 {
     StatusASO reset = new StatusASO(StatusASO.NS_PLAY_RESET);
     reset.clientid = this.StreamId;
     reset.details = item.Name;
     reset.description = "Playing and resetting " + item.Name + '.';
     StatusMessage resetMsg = new StatusMessage();
     resetMsg.body = reset;
     DoPushMessage(resetMsg);
 }
Пример #43
0
		public void AddItem(IPlayItem item, int index) {
			lock (this.SyncRoot) {
				_items.Insert(index, item);
			}
		}
Пример #44
0
		/// <summary>
		/// Notifies subscribers on item stop
		/// </summary>
		/// <param name="item">Item that just has been stopped.</param>
		internal void NotifyItemStop(IPlayItem item) {
			IStreamAwareScopeHandler handler = GetStreamAwareHandler();
			if (handler != null) {
				try {
					handler.StreamPlaylistItemStop(this, item);
				} catch (Exception ex) {
					log.Error("Error notify streamPlaylistItemStop", ex);
				}
			}
		}
Пример #45
0
        /// <summary>
        /// Stream not found status notification
        /// </summary>
        /// <param name="item"></param>
        private void SendStreamNotFoundStatus(IPlayItem item)
        {
            StatusASO notFound = new StatusASO(StatusASO.NS_PLAY_STREAMNOTFOUND);
            notFound.clientid = this.StreamId;
            notFound.level = StatusASO.ERROR;
            notFound.details = item.Name;

            StatusMessage notFoundMsg = new StatusMessage();
            notFoundMsg.body = notFound;
            DoPushMessage(notFoundMsg);
        }
Пример #46
0
 /// <summary>
 /// Send seek status notification
 /// </summary>
 /// <param name="item"></param>
 /// <param name="position"></param>
 private void SendSeekStatus(IPlayItem item, int position)
 {
     StatusASO seek = new StatusASO(StatusASO.NS_SEEK_NOTIFY);
     seek.clientid = this.StreamId;
     seek.details = item.Name;
     seek.description = "Seeking " + position + " (stream ID: " + this.StreamId + ").";
     StatusMessage seekMsg = new StatusMessage();
     seekMsg.body = seek;
     DoPushMessage(seekMsg);
 }
Пример #47
0
        /// <summary>
        /// Insufficient bandwidth notification
        /// </summary>
        /// <param name="item"></param>
        private void SendInsufficientBandwidthStatus(IPlayItem item)
        {
            StatusASO insufficientBW = new StatusASO(StatusASO.NS_PLAY_INSUFFICIENT_BW);
            insufficientBW.clientid = this.StreamId;
            insufficientBW.level = StatusASO.WARNING;
            insufficientBW.details = item.Name;
            insufficientBW.description = "Data is playing behind the normal speed.";

            StatusMessage insufficientBWMsg = new StatusMessage();
            insufficientBWMsg.body = insufficientBW;
            DoPushMessage(insufficientBWMsg);
        }