Ejemplo n.º 1
0
        public static void StopRecording()
        {
            if (!Recording)
            {
                return;
            }

            Duration += (Time.time - StartTime);

            if (!Recording)
            {
                return;
            }

            Recording = false;

            //while(FfmpegFrameSent < FfmpegFrameRendered)
            //{
            //    Thread.Sleep(50);
            //}

            FfmpegStream.Close();
            FfmpegStream = null;
            FfmpegProcess.Close();
            FfmpegProcess = null;

            Time.captureFramerate = 0;

            RecordingStopped();
        }
Ejemplo n.º 2
0
            public void Close()
            {
                Closed = true;

                try
                {
                    if (!FfmpegProcess.HasExitedSafe())
                    {
                        FfmpegProcess.Kill();
                    }
                }
                catch { }
                try { FfmpegProcess.CancelErrorRead(); } catch { }
                try { FfmpegProcess.StandardInput.Dispose(); } catch { }
                try { FfmpegProcess.StandardOutput.Dispose(); } catch { }
                try { FfmpegProcess.Dispose(); } catch { }

                IcyStream?.Dispose();
            }
Ejemplo n.º 3
0
 public void Initialize()
 {
     _process         = new Mock <IProcessAsync>();
     _tempFileManager = new Mock <ITempFileManager>();
     _ffmpeg          = new FfmpegProcess(_process.Object, _tempFileManager.Object);
 }
Ejemplo n.º 4
0
        private void PlaybackThreadStart(object obj)
        {
            var objs = (object[])obj;
            var cancellationToken = (CancellationToken)objs[0];

            int sampleRate   = 48000;
            int channelCount = 2;

            string format = BitConverter.IsLittleEndian ? "f32le" : "f32be";
            string codec  = "pcm_" + format;

            var playerArguments = new ArgumentList()
                                  .Add("-v").Add("fatal")
                                  .Add("-autoexit")
                                  .Add("-nodisp")
                                  .Add("-ar").Add(sampleRate.ToStringInvariant())
                                  .Add("-ac").Add(channelCount.ToStringInvariant())
                                  .Add("-f").Add(format)
                                  .Add("-");

            using (var serviceScope = _serviceScopeFactory.CreateScope())
            {
                var dbContext = serviceScope.ServiceProvider.GetRequiredService <MediaInfoContext>();

restartPlayer:
                // Wait for playing.
                for (; ;)
                {
                    if (cancellationToken.IsCancellationRequested)
                    {
                        return;
                    }

                    lock (_lock)
                    {
                        if (_playing)
                        {
                            break;
                        }
                    }

                    WaitHandle.WaitAny(new[] { cancellationToken.WaitHandle, _playEvent });
                }

                using (var playerProcess = new FfmpegProcess("ffplay", playerArguments))
                    using (var playerStream = playerProcess.InputStream)
                    {
                        var sampleBuffer = new float[sampleRate / 20 * channelCount];
                        var buffer       = MemoryMarshal.AsBytes(sampleBuffer.AsSpan());

restartTrack:
                        for (; ;)
                        {
                            if (cancellationToken.IsCancellationRequested)
                            {
                                return;
                            }

                            int playerTrackId;
                            int playerTrackPositionSamples;
                            int playerTrackPosition;

                            lock (_lock)
                            {
                                if (!_playing)
                                {
                                    goto restartPlayer;
                                }

                                int trackId = _playlistIndex != -1 ? _playlist[_playlistIndex] : -1;
                                if (trackId == -1)
                                {
                                    goto nextTrack;
                                }

                                playerTrackId = trackId;
                                playerTrackPositionSamples = _trackPosition * sampleRate * channelCount;
                                playerTrackPosition        = _trackPosition;
                            }

                            var track = dbContext.Tracks
                                        // where track is current jukebox track
                                        .Where(t => t.TrackId == playerTrackId)
                                        // find files for tracks
                                        .Join(dbContext.Files, t => t.FileId, f => f.FileId, (t, f) => new
                            {
                                LibraryPath   = f.Library.Path,
                                DirectoryPath = f.Directory.Path,
                                FileName      = f.Name,
                                t.StreamIndex,
                                t.AlbumGain,
                                t.TrackGain,
                            })
                                        .FirstOrDefault();
                            if (track == null)
                            {
                                goto nextTrack;
                            }

                            string filePath = Path.Join(track.LibraryPath, track.DirectoryPath, track.FileName);

                            var decoderArguments = new ArgumentList()
                                                   .Add("-i").Add(filePath)
                                                   .Add("-ss").Add(playerTrackPosition.ToStringInvariant())
                                                   .Add("-map").Add(b => b.Append("0:").Append(track.StreamIndex.ToStringInvariant()))
                                                   .Add("-c:a:0").Add(codec)
                                                   .Add("-ar:0").Add(sampleRate.ToStringInvariant())
                                                   .Add("-ac:0").Add(channelCount.ToStringInvariant())
                                                   .Add("-f").Add(format)
                                                   .Add("-");

                            using (var decoderProcess = FfmpegTranscoder.Transcode(decoderArguments))
                                using (var decoderStream = decoderProcess.OutputStream)
                                {
                                    decoderProcess.InputStream.Close();

                                    float replayGainScale = MathF.Pow(10, (track.TrackGain ?? 0) / 20);

                                    int bufferOffset = 0;
                                    int bufferCount  = 0;

                                    for (; ;)
                                    {
                                        if (cancellationToken.IsCancellationRequested)
                                        {
                                            return;
                                        }

                                        lock (_lock)
                                        {
                                            if (!_playing)
                                            {
                                                goto restartPlayer;
                                            }

                                            int trackId = _playlistIndex != -1 ? _playlist[_playlistIndex] : -1;
                                            if (playerTrackId != trackId || playerTrackPosition != _trackPosition)
                                            {
                                                goto restartTrack;
                                            }

                                            playerTrackPosition = playerTrackPositionSamples / (sampleRate * channelCount);
                                            _trackPosition      = playerTrackPosition;
                                        }

                                        try
                                        {
                                            int readCount = decoderStream.Read(buffer.Slice(bufferOffset + bufferCount));
                                            if (readCount == 0)
                                            {
                                                break;
                                            }
                                            bufferCount += readCount;
                                        }
                                        catch (IOException ex)
                                        {
                                            Debug.WriteLine("Exception thrown while reading from ffmpeg: {0}", ex);
                                            break;
                                        }

                                        var samplesSpan = sampleBuffer.AsSpan(bufferOffset / sizeof(float), bufferCount / sizeof(float));

                                        float scale = replayGainScale * _gainScale;
                                        for (int i = 0; i < samplesSpan.Length; ++i)
                                        {
                                            samplesSpan[i] *= scale;
                                        }

                                        try
                                        {
                                            int writeCount = samplesSpan.Length * sizeof(float);
                                            playerStream.Write(buffer.Slice(bufferOffset, writeCount));
                                            bufferOffset += writeCount;
                                            bufferCount  -= writeCount;
                                        }
                                        catch (IOException ex)
                                        {
                                            Debug.WriteLine("Exception thrown while writing to ffplay: {0}", ex);
                                            goto restartPlayer;
                                        }

                                        if (bufferCount == 0)
                                        {
                                            bufferOffset = 0;
                                        }

                                        playerTrackPositionSamples += samplesSpan.Length;
                                    }
                                }

nextTrack:
                            lock (_lock)
                            {
                                if (_playlistIndex + 1 < _playlist.Count)
                                {
                                    _playlistIndex += 1;
                                    _trackPosition  = 0;
                                }
                                else
                                {
                                    _playing       = false;
                                    _playlistIndex = -1;
                                    _trackPosition = 0;

                                    goto restartPlayer;
                                }
                            }
                        }
                    }
            }
        }