コード例 #1
0
        /*
         * private ;
         * private ;
         *
         * private ;
         * private ;
         */
        public void Init(string filePath, PlayRange playRange, MPlaylistSettings mplaylistSettings,
                         Func <bool> canSetInAction, Action <double> setInAction, Func <bool> canSetOutAction, Action <double> setOutAction)
        {
            var timer = new DispatcherTimer();

            timer.Interval = TimeSpan.FromMilliseconds(33);

            if (_player == null)
            {
                _player = new PlayControlModel2.Player2(mplaylistSettings);
            }
            _viewModel = new PlayControlModel2(timer /*,this.Dispatcher*/, mplaylistSettings, _player)
            {
                _canSetOutAction = canSetOutAction,
                _canSetInAction  = canSetInAction,
                _setInAction     = setInAction,
                _setOutAction    = setOutAction
            };


            _viewModel.Opened += OnOpened;
            _viewModel.Closed += OnClosed;

            _viewModel.FileName  = filePath;
            _viewModel.PlayRange = playRange;


            this.DataContext = _viewModel;
        }
コード例 #2
0
ファイル: MediaItemUtils.cs プロジェクト: jwming05/FCSPlayout
        public static MediaItem FromEntity(MediaFileEntity entity)
        {
            MediaSourceBase source    = new FileMediaSource(entity);
            PlayRange       playRange = new PlayRange(TimeSpan.FromSeconds(entity.MarkerIn), TimeSpan.FromSeconds(entity.MarkerDuration));

            return(new MediaItem(source, playRange));
        }
コード例 #3
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);
        }
コード例 #4
0
 public void SetLoopRange(PlayRange range)
 {
     lock (objLock)
     {
         loopRange = range;
     }
 }
コード例 #5
0
 public override PlayRange?Adjust(PlayRange playRange)
 {
     if (playRange.StartPosition == TimeSpan.Zero && playRange.Duration == this.Duration.Value)
     {
         return(null);
     }
     return(playRange);
 }
コード例 #6
0
        public ChannelItemListViewModel(IRegionManager regionManager)
        {
            this.Channels = new List <ChannelMediaSource>(PlayoutRepository.GetChannelInfos(true).Select(i => new ChannelMediaSource(i)));

            // TODO: 从配置中获取默认时长。
            _playRange = new PlayRange(TimeSpan.FromMinutes(30));

            _regionManager = regionManager;
        }
コード例 #7
0
        /// <summary>
        /// Sets the range of the sound to play.
        /// </summary>
        /// <param name="range">a PlayRange structure that describes the starting offset and ending point of the sound to play in seconds.</param>
        public override void SetPlayRange(PlayRange range)
        {
            lock (rangeLock)
            {
                playRange = range;
            }

            base.SetPlayRange(range);
        }
コード例 #8
0
        partial void UpdateImpl(ref TimeSpan elapsed)
        {
            if (videoOutputSurface == null || PlayState == PlayState.Stopped)
            {
                return;
            }

            //Transfer frame if a new one is available
            if (mediaEngine.OnVideoStreamTick(out var presentationTimeTicks))
            {
                CurrentTime = TimeSpan.FromTicks(presentationTimeTicks);

                // Check end of media
                var endOfMedia = reachedEOF;
                if (!endOfMedia)
                {
                    //check the video loop and play range
                    if (PlayRange.IsValid() && CurrentTime > PlayRange.End)
                    {
                        endOfMedia = true;
                    }
                    else if (IsLooping && LoopRange.IsValid() && CurrentTime > LoopRange.End)
                    {
                        endOfMedia = true;
                    }
                }

                if (endOfMedia)
                {
                    if (IsLooping)
                    {
                        //Restart the video at LoopRangeStart
                        Seek(LoopRange.Start);
                    }
                    else
                    {
                        //stop the video
                        Stop();
                        return;
                    }
                }

                if (videoComponent.Target != null && videoOutputSurface != null && videoOutputTexture != null)
                {
                    videoTexture.SetTargetContentToVideoStream(videoComponent.Target);

                    // Now update the video texture with data of the new video frame:
                    var graphicsContext = services.GetSafeServiceAs <GraphicsContext>();

                    mediaEngine.TransferVideoFrame(videoOutputSurface, null, new SharpDX.Mathematics.Interop.RawRectangle(0, 0, videoWidth, videoHeight), null);
                    videoTexture.CopyDecoderOutputToTopLevelMipmap(graphicsContext, videoOutputTexture);

                    videoTexture.GenerateMipMaps(graphicsContext);
                }
            }
        }
コード例 #9
0
ファイル: PlayScheduler.cs プロジェクト: jwming05/FCSPlayout
            public PlayItemWrapper(IPlayItem item, DateTime expectedPlayTime) : this(item)
            {
                Debug.Assert(expectedPlayTime > item.StartTime);

                this.ExpectedPlayTime = expectedPlayTime;

                //var oldRange = item.PlayRange;
                TimeSpan delta = expectedPlayTime.Subtract(item.StartTime);

                var newStartPos = _playRange.StartPosition + delta;

                _playRange = new PlayRange(newStartPos, _playRange.StopPosition - newStartPos);
            }
コード例 #10
0
ファイル: PlayScheduler.cs プロジェクト: jwming05/FCSPlayout
            public PlayItemWrapper(IPlayItem item)
            {
                this.PlayItem = item;
                _playRange    = new PlayRange(item.PlayRange.StartPosition, item.CalculatedPlayDuration);

                this.ExpectedPlayTime = item.StartTime;
                if (item.PlaybillItem.CGItems != null)
                {
                    this.CGItems = item.PlaybillItem.CGItems.Clone();
                }

                this.MediaSource = item.PlaybillItem.MediaSource; //.Clone();
            }
コード例 #11
0
        //==========================================================================================

        /// <summary>
        /// This type of DynamicSoundSource is streamed from Disk and reads compressed Celt encoded data, used internally.
        /// </summary>
        /// <param name="instance">The associated SoundInstance</param>
        /// <param name="fileProvider">The file provider to read the stream from</param>
        /// <param name="soundStreamUrl">The compressed stream internal URL</param>
        /// <param name="numberOfPackets"></param>
        /// <param name="sampleRate">The sample rate of the compressed data</param>
        /// <param name="channels">The number of channels of the compressed data</param>
        /// <param name="maxCompressedSize">The maximum size of a compressed packet</param>
        public CompressedSoundSource(SoundInstance instance, IVirtualFileProvider fileProvider, string soundStreamUrl, int numberOfPackets, int sampleRate, int channels, int maxCompressedSize) :
            base(instance, NumberOfBuffers, SamplesPerBuffer * MaxChannels * sizeof(short))
        {
            looped                 = instance.IsLooping;
            this.channels          = channels;
            this.maxCompressedSize = maxCompressedSize;
            this.fileProvider      = fileProvider;
            this.soundStreamUrl    = soundStreamUrl;
            this.sampleRate        = sampleRate;
            this.numberOfPackets   = numberOfPackets;
            playRange              = new PlayRange(TimeSpan.Zero, TimeSpan.Zero);

            NewSources.Add(this);
        }
コード例 #12
0
 private void ChangePlayRange(IPlayItem playItem, PlayRange newRange)
 {
     try
     {
         _playlistEditor.ChangePlayRange(playItem, newRange);
     }
     catch (Exception ex)
     {
         ((NewPlaylistEditor)_playlistEditor).Rollback();
         if (_onError != null)
         {
             _onError(ex);
         }
     }
 }
コード例 #13
0
        public CompressedSoundSource(SoundInstance instance, byte[] byteBuffer, int numberOfPackets, int numberOfSamples, int sampleRate, int channels, int maxCompressedSize)
            : base(instance, NumberOfBuffers, SamplesPerBuffer * MaxChannels * sizeof(short))
        {
            looped                 = instance.IsLooping;
            this.channels          = channels;
            this.maxCompressedSize = maxCompressedSize;
            this.soundStreamUrl    = null;
            this.byteBuffer        = byteBuffer;
            this.sampleRate        = sampleRate;
            this.numberOfPackets   = numberOfPackets;
            this.samples           = numberOfSamples;
            playRange              = new PlayRange(TimeSpan.Zero, TimeSpan.Zero);

            NewSources.Enqueue(this);
        }
コード例 #14
0
        /// <summary>
        /// This type of DynamicSoundSource is streamed from Disk and reads compressed Celt encoded data, used internally.
        /// </summary>
        /// <param name="instance">The associated SoundInstance</param>
        /// <param name="soundStreamUrl">The compressed stream internal URL</param>
        /// <param name="numberOfPackets"></param>
        /// <param name="sampleRate">The sample rate of the compressed data</param>
        /// <param name="channels">The number of channels of the compressed data</param>
        /// <param name="maxCompressedSize">The maximum size of a compressed packet</param>
        public CompressedSoundSource(SoundInstance instance, string soundStreamUrl, int numberOfPackets, int sampleRate, int channels, int maxCompressedSize) : base(instance, NumberOfBuffers, SamplesPerBuffer * MaxChannels * sizeof(short))
        {
            looped = instance.IsLooping;
            this.channels = channels;
            this.maxCompressedSize = maxCompressedSize;
            this.soundStreamUrl = soundStreamUrl;
            this.sampleRate = sampleRate;
            this.numberOfPackets = numberOfPackets;
            playRange = new PlayRange(TimeSpan.Zero, TimeSpan.Zero);

            if (readFromDiskWorker == null)
            {
                readFromDiskWorker = Task.Factory.StartNew(Worker, TaskCreationOptions.LongRunning);
            }

            NewSources.Add(this);
        }
コード例 #15
0
        private PlayRange SetInOut(MItem mitem, PlayRange playRange)
        {
            double dblIn = 0.0, dblOut = 0.0;

            dblIn  = playRange.StartPosition.TotalSeconds;
            dblOut = playRange.StopPosition.TotalSeconds;

            mitem.FileInOutSet(dblIn, dblOut);

            double dblDuration;

            mitem.FileInOutGet(out dblIn, out dblOut, out dblDuration);
            if (dblOut == dblIn || dblOut == 0.0)
            {
                dblOut = dblDuration;
            }

            return(new PlayRange(TimeSpan.FromSeconds(dblIn), TimeSpan.FromSeconds(dblOut - dblIn)));
        }
コード例 #16
0
 private void ChangeSource()
 {
     if (CanChangeSource())
     {
         var builder = CreateBuilder();
         try
         {
             var newRange = new PlayRange(this._selectedMediaItem.Value.PlayRange.StartPosition,
                                          this.SelectedPlayItem.PlayItem.CalculatedPlayDuration);
             builder.ChangeSource(this.SelectedPlayItem.PlayItem, this.SelectedMediaItem.Value.Source, newRange);
             Rebuild(builder);
         }
         catch (Exception ex)
         {
             //editor.Rollback();
             OnError(ex);
         }
     }
 }
コード例 #17
0
ファイル: MediaItemUtils.cs プロジェクト: jwming05/FCSPlayout
        public static MediaItem FromEntity(MediaSourceEntity entity)
        {
            MediaSourceBase source = MediaSourceBase.Create(entity);

            var       fileEntity = entity as MediaFileEntity;
            PlayRange playRange;

            if (fileEntity != null)
            {
                playRange = new PlayRange(TimeSpan.FromSeconds(fileEntity.MarkerIn),
                                          TimeSpan.FromSeconds(fileEntity.MarkerDuration));
            }
            else
            {
                playRange = new PlayRange(PlayoutConfiguration.Current.DefaultDuration);
            }

            return(new MediaItem(source, playRange));
        }
コード例 #18
0
        private static IPlaySource Create(PlaybillItemEntity entity, IMediaSource mediaSource)
        {
            var range = new PlayRange(TimeSpan.FromSeconds(entity.MarkerIn), TimeSpan.FromSeconds(entity.MarkerDuration));

            CGItemCollection cgItems = null;


            if (entity.CGContents != null)
            {
                cgItems = CGItemCollection.FromXml(entity.CGContents);
            }

            if (cgItems == null)
            {
                return(new PlaySource(mediaSource, range));
            }
            else
            {
                return(new PlaySource(mediaSource, range, cgItems));
            }
        }
コード例 #19
0
 public void ChangePlayRange(IPlayableItem playItem, PlayRange newRange)
 {
     this.ChangePlayRange(playItem.PlayItem, newRange);
 }
コード例 #20
0
        partial void UpdateImpl(ref TimeSpan elapsed)
        {
            if (stream == null)
            {
                return;
            }

            if (PlayState == PlayState.Stopped)
            {
                return;
            }

            var speedFactor = SpeedFactor;

            if (PlayState == PlayState.Paused)
            {
                speedFactor = 0;
            }

            // Compare elapsed time with video framerate
            var frameDurationTicks = stream.FrameDuration.Ticks;

            adjustedTicksSinceLastFrame += (long)(elapsed.Ticks * speedFactor);
            if (adjustedTicksSinceLastFrame < frameDurationTicks)
            {
                return;
            }

            var frameCount = (int)(adjustedTicksSinceLastFrame / frameDurationTicks);

            if (frameCount == 0)
            {
                // Note: in case of slow speed factor, we might not need to update at each draw
                return;
            }

            if (frameCount > 4)
            {
                // Reading more than a few frames can be expensive, better seek.
                // FIXME: we might need a heuristic here to auto-adapt. It is probably dependent on the video being played (e.g. resolution, codec, file size, etc.)
                Seek(CurrentTime + TimeSpan.FromTicks(frameDurationTicks * frameCount));
                frameCount = 1;
            }

            // Extract the frames
            var extractedFrameCount = media.ExtractFrames(stream, frameCount);

            if (extractedFrameCount > 0)
            {
                adjustedTicksSinceLastFrame = adjustedTicksSinceLastFrame % stream.FrameDuration.Ticks;
            }

            // Get the last one
            var streamInfo = media.GetStreamInfo(stream);

            if (streamInfo?.Image == null)
            {
                return;
            }

            // Check end of media
            bool endOfMedia = streamInfo.ReachedEnd;

            if (!endOfMedia)
            {
                if (extractedFrameCount > 0)
                {
                    CurrentTime = stream.TimestampToTime(streamInfo.Image.Timestamp);
                }

                //check the video loop and play range
                if (PlayRange.IsValid() && CurrentTime > PlayRange.End)
                {
                    endOfMedia = true;
                }
                else if (IsLooping && LoopRange.IsValid() && CurrentTime > LoopRange.End)
                {
                    endOfMedia = true;
                }
            }

            if (endOfMedia)
            {
                if (IsLooping)
                {
                    //Restart the video at LoopRangeStart
                    //(ToCheck: is there a better way to do this (directly updating CurrentTime does not seem good, but if not doing, it will not work))
                    CurrentTime = LoopRange.Start;
                    Seek(LoopRange.Start);
                    return;
                }
                else
                {
                    //stop the video
                    Stop();
                    return;
                }
            }

            // return if the frame extraction failed and didn't reached and of the video
            if (extractedFrameCount == 0)
            {
                return;
            }

            if (videoComponent.Target != null)
            {
                videoTexture.SetTargetContentToVideoStream(videoComponent.Target);

                // Now update the video texture with data of the new video frame:
                var graphicsContext = services.GetSafeServiceAs <GraphicsContext>();

                if (streamInfo.Codec.IsHardwareAccelerated && streamInfo.Image == null)
                {
                    videoTexture.CopyDecoderOutputToTopLevelMipmap(graphicsContext, streamInfo.Codec.DecoderOutputTexture);
                }
                else
                {
                    videoTexture.UpdateTopLevelMipmapFromData(graphicsContext, streamInfo.Image);
                }

                videoTexture.GenerateMipMaps(graphicsContext);
            }
        }
コード例 #21
0
 /// <summary>
 /// Sets the range of the sound to play.
 /// </summary>
 /// <param name="range">a PlayRange structure that describes the starting offset and ending point of the sound to play in seconds.</param>
 /// <remarks>This will not be valid if the sound is played with PlayAndForget</remarks>
 public void SetRange(PlayRange range)
 {
     foreach (var instance in InstanceToListener)
     {
         instance.Key.SetRange(range);
     }
 }
コード例 #22
0
        //public Guid Id
        //{
        //    get; set;
        //}

        public override PlayRange?Adjust(PlayRange playRange)
        {
            return(new PlayRange(TimeSpan.Zero, playRange.Duration));
        }
コード例 #23
0
 /// <summary>
 /// Sets the region of time to play from the audio clip.
 /// </summary>
 /// <param name="range">a PlayRange structure that describes the starting offset and ending point of the sound to play in seconds.</param>
 public virtual void SetRange(PlayRange range)
 {
     Commands.Enqueue(AsyncCommand.SetRange);
 }
コード例 #24
0
 public EditMediaItemConfirmation(string filePath, PlayRange playRange)
 {
     _filePath  = filePath;
     _playRange = playRange;
 }
コード例 #25
0
 /// <summary>
 /// Sets the region of time to play from the audio clip.
 /// </summary>
 /// <param name="range">a PlayRange structure that describes the starting offset and ending point of the sound to play in seconds.</param>
 public virtual void SetPlayRange(PlayRange range)
 {
     Commands.Enqueue(AsyncCommand.SetRange);
 }
コード例 #26
0
 public virtual PlayRange?Adjust(PlayRange playRange)
 {
     return(playRange);
 }
コード例 #27
0
        /// <summary>
        /// Sets the range of the sound to play.
        /// </summary>
        /// <param name="range">a PlayRange structure that describes the starting offset and ending point of the sound to play in seconds.</param>
        public void SetRange(PlayRange range)
        {
            if (engine.State == AudioEngineState.Invalidated)
                return;

            var state = PlayState;

            if (state == SoundPlayState.Playing)
            {
                Stop();
            }

            if (soundSource == null)
            {
                AudioLayer.SourceSetRange(Source, range.Start.TotalSeconds, range.End.TotalSeconds);               
            }
            else
            {
                soundSource.SetRange(range);
            }

            if (state == SoundPlayState.Playing)
            {
                Play();
            }
        }
コード例 #28
0
        /// <summary>
        /// Sets the range of the sound to play.
        /// </summary>
        /// <param name="range">a PlayRange structure that describes the starting offset and ending point of the sound to play in seconds.</param>
        public override void SetRange(PlayRange range)
        {
            lock (rangeLock)
            {
                playRange = range;
            }

            base.SetRange(range);
        }