// 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); }); }
public IPlaySource Clone() { var result = new PlaySource(this.MediaSource, this.PlayRange); if (this.CGItems != null) { result.CGItems = this.CGItems.Clone(); } return(result); }
internal void ChangeSource(IPlayItem playItem, IMediaSource newSource, PlayRange?newRange) { int index = _playItems.IndexOf(playItem); if (index < 0) { throw new ArgumentException(); } IPlayItem newPlayItem = null; if (newRange != null && playItem.ScheduleMode != PlayScheduleMode.Auto) { if (newRange.Value.Duration > playItem.PlayRange.Duration) { var newStopTime = playItem.StartTime.Add(newRange.Value.Duration); if (this.HasTimingConflict(playItem.StartTime, newStopTime, playItem)) { throw new InvalidOperationException(); } } } else { } newRange = newRange == null ? new PlayRange(TimeSpan.Zero, playItem.CalculatedPlayDuration) : newRange.Value; var newPlaySource = new PlaySource(newSource, newRange.Value, playItem.PlaybillItem.PlaySource.CGItems); switch (playItem.ScheduleMode) { case PlayScheduleMode.Auto: newPlayItem = new AutoPlayItem(AutoPlaybillItem.Auto(newPlaySource)); break; case PlayScheduleMode.Timing: newPlayItem = (IPlayItem)TimingPlaybillItem.Timing(newPlaySource, playItem.StartTime); break; case PlayScheduleMode.TimingBreak: newPlayItem = (IPlayItem)TimingPlaybillItem.TimingBreak(newPlaySource, playItem.StartTime); break; } _playItems[index] = newPlayItem; this.IsDirty = true; }
// case1: 修改定时播或定时插播的开始时间。 // case2: 定时播改为定时插播。 // case3: 定时插播改为定时播。 // case4: 顺播改为定时播或定时插播。 private void ChangeToTimingScheduleInternal(IPlayItem playItem, PlayScheduleMode?scheduleMode, DateTime?startTime) { var newScheduleMode = scheduleMode ?? playItem.ScheduleMode; Debug.Assert(newScheduleMode == PlayScheduleMode.Timing || newScheduleMode == PlayScheduleMode.TimingBreak); //if (_playlist.IsLocked(playItem)) throw new PlayItemLockedException(); var newStartTime = startTime ?? playItem.StartTime; if (playItem.ScheduleMode == newScheduleMode && playItem.StartTime == newStartTime) { return; } var playRange = playItem.PlayRange; //_playlist.ValidateTimeRange(newStartTime, playRange.Duration, playItem); ValidateTimeRange(newStartTime, playRange.Duration, playItem); // NOTE: 对于顺播PlayRange可能需要改变,因此不能简单的克隆PlaySource。 var playSource = new PlaySource(playItem.MediaSource /*.Clone()*/, playRange, playItem.CGItems); var newItem = newScheduleMode == PlayScheduleMode.Timing ? PlaybillItem.Timing(playSource, newStartTime) : PlaybillItem.TimingBreak(playSource, newStartTime); /* * 修改定时播开始时间。不能跨越前后定时播。 * 修改定时插播开始时间。不能向前跨越第一个定时播。 */ if (scheduleMode == null && startTime != null) { if (playItem.ScheduleMode == PlayScheduleMode.Timing) { // 查找前一个定时播。 var prevTuple = this.FindLastTiming(i => i.StartTime < playItem.StartTime /*startTime.Value*/); if (prevTuple.Item2 != -1) { // 如果前面有定时播,则开始时间不能小于前面定时播的结束时间。 if (startTime.Value < prevTuple.Item1.CalculatedStopTime) { throw new ArgumentException(); } } // 查找后一个定时播。 var nextTuple = this.FindFirstTiming(i => i.StartTime > playItem.StartTime /*startTime.Value*/); if (nextTuple.Item2 != -1) { // 如果后面有定时播,则结束时间不能大于后面定时播的开始时间。 if (startTime.Value.Add(playItem.PlayRange.Duration) > prevTuple.Item1.StartTime) { throw new ArgumentException(); } } var currentTuple = this.FindFirstTiming(i => i.PlayItem == playItem); if (currentTuple.Item2 != 0) { // 如果前面有片断,则更新前面片断。 var begin1 = prevTuple.Item2 == -1 ? 0 : prevTuple.Item2 + 1; this.Rebuild(_playlist[begin1].StartTime < startTime.Value ? _playlist[begin1].StartTime : startTime.Value, startTime.Value, begin1, currentTuple.Item2 - 1, null); } // 更新本片断。 var temp = (IPlayItem)newItem; _playlist[currentTuple.Item2] = new ScheduleItem(temp); this.Rebuild(temp.CalculatedStopTime, nextTuple.Item2 == -1 ? DateTime.MaxValue : nextTuple.Item1.StartTime /*stopTime*/, currentTuple.Item2 + 1, nextTuple.Item2 == -1 ? _playlist.Count - 1 : nextTuple.Item2 - 1, null); return; } else if (playItem.ScheduleMode == PlayScheduleMode.TimingBreak) { //var prevTuple = this.FindLastTiming(i => i.StartTime < startTime.Value); //if (prevTuple.Item2 == -1) //{ // if (startTime.Value < prevTuple.Item1.CalculatedStopTime) // { // throw new ArgumentException(); // } //} } else { } } this.Delete(playItem); this.AddTiming((IPlayItem)newItem); }
/// <summary> /// 把指定的顺播上移一个位置。 /// </summary> /// <param name="playItem"></param> public void MoveUp(IPlayItem playItem) { Debug.Assert(playItem.ScheduleMode == PlayScheduleMode.Auto); //if (_playlist.IsLocked(playItem)) throw new PlayItemLockedException(); if (_playlist[0] == playItem) { return; } //var index = _playlist.FindFirstIndex(i => i == playItem); var index = _playlist.FindIndex(i => i.PlayItem == playItem); if (index == -1) { throw new ArgumentException(); } if (index >= 2) { var newPrevItem = _playlist[index - 2]; //Reorder(newPrevItem, playItem); Reorder(newPrevItem.PlayItem, playItem); } else { Debug.Assert(index == 1); var oldPrevItem = _playlist[0]; if (oldPrevItem.ScheduleMode == PlayScheduleMode.Timing || oldPrevItem.ScheduleMode == PlayScheduleMode.TimingBreak) { return; } var playSource = new PlaySource(playItem.MediaSource /*.Clone()*/, playItem.PlayRange, playItem.CGItems); var newAutoItem = new AutoPlayItem(PlaybillItem.Auto(playSource)); var nextTuple = this.FindFirstTiming(index + 1, (i) => true); DateTime startTime = oldPrevItem.StartTime; int beginIndex = 0; DateTime stopTime; int endIndex; if (nextTuple.Item2 == -1) { stopTime = DateTime.MaxValue; endIndex = _playlist.Count - 1; } else { stopTime = nextTuple.Item1.StartTime; endIndex = nextTuple.Item2 - 1; } this.Rebuild(startTime, stopTime, beginIndex, endIndex, (items) => { items.RemoveAt(1); items.Insert(0, new ScheduleItem(newAutoItem)); }); } }