示例#1
0
        /// <summary>
        /// Prepares for writing.
        /// </summary>
        /// <param name="showFFmpegOutput">Show output to terminal. Error stream will not be redirected if this is set to true.</param>
        /// <param name="thread_queue_size">Max. number of queued packets when reading from file/stream.
        /// Should be set to higher when dealing with high rate/low latency streams.</param>
        public void OpenWrite(bool showFFmpegOutput = false, int thread_queue_size = 4096)
        {
            if (OpenedForWriting)
            {
                throw new InvalidOperationException("File/Stream was already opened for writing!");
            }

            var manual = new ManualResetEvent(false);

            socket = new Socket(SocketType.Stream, ProtocolType.Tcp);
            socket.Bind(new IPEndPoint(IPAddress.Loopback, 0));
            socket.Listen(4);
            var port = ((IPEndPoint)socket.LocalEndPoint).Port;

            socket.BeginAccept(r =>
            {
                connected_socket     = socket.EndAccept(r);
                InputDataStreamAudio = new NetworkStream(connected_socket);
                manual.Set();
            }, null);

            var cmd = $"-f s{AudioBitDepth}le -channels {AudioChannels} -sample_rate {AudioSampleRate} " +
                      $"-thread_queue_size {thread_queue_size} -i \"tcp://{IPAddress.Loopback}:{port}\" " +
                      $"-f rawvideo -video_size {VideoWidth}:{VideoHeight} -r {VideoFramerate} " +
                      $"-thread_queue_size {thread_queue_size} -pixel_format rgb24 -i - " +
                      $"-map 0 -c:a {AudioEncoderOptions.EncoderName} {AudioEncoderOptions.EncoderArguments} " +
                      $"-map 1 -c:v {VideoEncoderOptions.EncoderName} {VideoEncoderOptions.EncoderArguments} " +
                      $"-f {VideoEncoderOptions.Format}";

            if (UseFilename)
            {
                if (File.Exists(Filename))
                {
                    File.Delete(Filename);
                }

                InputDataStreamVideo = FFmpegWrapper.OpenInput(ffmpeg, $"{cmd} \"{Filename}\"", out ffmpegp, showFFmpegOutput);
            }
            else
            {
                csc = new CancellationTokenSource();

                // using stream
                (InputDataStreamVideo, OutputDataStream) = FFmpegWrapper.Open(ffmpeg, $"{cmd} -", out ffmpegp, showFFmpegOutput);
                _ = OutputDataStream.CopyToAsync(DestinationStream, csc.Token);
            }

            manual.WaitOne();
            OpenedForWriting = true;
        }
示例#2
0
        /// <summary>
        /// Closes output video.
        /// </summary>
        public void CloseWrite()
        {
            if (!OpenedForWriting)
            {
                throw new InvalidOperationException("File is not opened for writing!");
            }

            try
            {
                InputDataStreamAudio?.Dispose();
                InputDataStreamVideo?.Dispose();

                connected_socket?.Shutdown(SocketShutdown.Both);
                connected_socket?.Close();
                socket?.Close();

                ffmpegp.WaitForExit();
                csc?.Cancel();

                if (!UseFilename)
                {
                    OutputDataStream?.Dispose();
                }

                try
                {
                    if (ffmpegp?.HasExited == false)
                    {
                        ffmpegp.Kill();
                    }
                }
                catch { }
            }
            finally
            {
                OpenedForWriting = false;
            }
        }
示例#3
0
 /// <summary>Sends a message of type RPY.</summary>
 /// <param name="stream">Data to send in the form of <code>OutputDataStream</code>.</param>
 /// <seealso cref="OutputDataStream"></seealso>
 /// <seealso cref="MessageStatus"></seealso>
 /// <returns>MessageStatus</returns>
 /// 
 /// <exception cref="BEEPException">if an error is encoutered or if messageType is
 /// not MESSAGE_TYPE_MSG.</exception>
 public virtual MessageStatus sendRPY(OutputDataStream stream)
 {
     throw new BEEPException(NOT_MESSAGE_TYPE_MSG);
 }
示例#4
0
 /// <summary>Sends a 'synchronous' request on this <code>SharedChannel</code>.</summary>
 /// <param name="ds"><code>DataStream</code> to send as this request's payload.</param>
 /// <returns>Reply Caller may block using this object to retrieve the reply
 /// to this request.</returns>
 /// <exception cref="BEEPException" />
 public virtual Reply sendRequest(OutputDataStream ds)
 {
     Reply r = new Reply();
     channel.sendMSG(ds, r);
     return r;
 }
示例#5
0
 /// <summary>Send a message of type MSG. Sends <code>stream</code> as message's
 /// payload.</summary>
 /// <param name="stream"><code>DataStream</code> that is read to send data.</param>
 /// <param name="replyListener"></param>
 /// <returns>MessageStatus Can be queried to get status information about the
 /// message.</returns>
 /// <seealso cref="OutputDataStream"></seealso>
 /// <seealso cref="MessageStatus"></seealso>
 /// <exception cref="BEEPException" />
 public virtual MessageStatus sendMSG(OutputDataStream stream, ReplyListener replyListener)
 {
     return channel.sendMSG(stream, replyListener);
 }