Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/340.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在C#应用程序中播放树莓皮h264流_C#_Stream_Ffmpeg_Raspberry Pi_H.264 - Fatal编程技术网

在C#应用程序中播放树莓皮h264流

在C#应用程序中播放树莓皮h264流,c#,stream,ffmpeg,raspberry-pi,h.264,C#,Stream,Ffmpeg,Raspberry Pi,H.264,我有一个覆盆子Pi板,带有专用摄像机,只能在h264中录制视频。我正在寻找在c#windows窗体应用程序中实时流式传输和播放录制视频的最佳方法(例如,延迟不到1秒)。另外的要求是,在显示之前可以容易地处理这样的流,例如用于搜索图像上的对象 我试过的东西: -raspi上的VLC服务器和c#forms应用程序中的VLC控件好的,所以实际上我设法解决了这个问题: 就像我前面说的-FPS120选项可以让玩家跳过buffer中的内容,并在收到后立即播放流。PanelId是mplayer嵌套的面板的句柄

我有一个覆盆子Pi板,带有专用摄像机,只能在h264中录制视频。我正在寻找在c#windows窗体应用程序中实时流式传输和播放录制视频的最佳方法(例如,延迟不到1秒)。另外的要求是,在显示之前可以容易地处理这样的流,例如用于搜索图像上的对象

我试过的东西:


-raspi上的VLC服务器和c#forms应用程序中的VLC控件好的,所以实际上我设法解决了这个问题:

就像我前面说的-FPS120选项可以让玩家跳过buffer中的内容,并在收到后立即播放流。PanelId是mplayer嵌套的面板的句柄

class Mplayer
{
    Process mplayer;

    public Mplayer(string path, string pipeName, int panelId)
    {
        String args = "";
        mplayer = new Process();
        mplayer.StartInfo.UseShellExecute = false;
        mplayer.StartInfo.RedirectStandardInput = true;
        mplayer.StartInfo.FileName = path;
        args = @"\\.\pipe\" + pipeName + " -demuxer +h264es -fps 120 -nosound -cache 512";
        args += " -nofs -noquiet -identify -slave ";
        args += " -nomouseinput -sub-fuzziness 1 ";
        args += " -vo direct3d, -ao dsound  -wid ";
        args += panelId;
        mplayer.StartInfo.Arguments = args;
    }

    public void Start()
    {
        mplayer.Start();
    }

    public void End()
    {
        mplayer.Kill();
    }
}
后台工作人员正在从套接字读取内容:

    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        try
        {
            pipeServ.WaitForConnection(); //opcjonalne?
            StreamWriter sw = new StreamWriter(pipeServ);
            sw.AutoFlush = true;

            tcpCamera = new TcpClient();
            tcpCamera.Connect(ipAddress, camPort);
            NetworkStream camStream = tcpCamera.GetStream();

            int read = 0;
            byte[] bytes = new byte[tcpCamera.ReceiveBufferSize];
            while (tcpCamera.Connected)
            {
                read = camStream.Read(bytes, 0, tcpCamera.ReceiveBufferSize);
                if (read > 0)
                    pipeServ.Write(bytes, 0, read);
            }
        }
        catch (IOException ex)
        {
            //Broken pipe - result of Mplayer exit
            //MessageBox.Show(ex.Message);
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }
在RaspberryPi上运行的脚本。Portnumber是端口rasp正在侦听的端口号

#!/bin/bash

raspivid --width 1280 --height 720 -t 9999999 --framerate 25 --output - | nc -l PORTNUMBER

我没有使用命名管道就解决了它。以下是如何:

注意:此解决方案仅适用于Linux

首先创建一个bash脚本
VideoStreamRecv.bash
<代码>$1是WindowID的参数,我们将把WinForm面板ID传递给这个bash脚本

#!/bin/bash -e
nc 127.0.0.1 5000 | mplayer -nosound -fps 120 -demuxer h264es -cache 1024 -wid $1 -
注意:将相机连接的树莓Pi的IP写入
127.0.0.1

创建你的C#项目。我在VisualStudio中创建了一个简单的Windows窗体应用程序项目。这里是整体外观

以下是课程:

Base.cs

MPlayer.cs

这类似于@CoreMeltdown,但这里我们调用bash脚本,为了关闭mplayer子进程,我们在
End
函数中调用pkill

class MPlayer
{
    Process mplayer;

    public MPlayer(int PanelID)
    {
        mplayer = new Process();
        mplayer.StartInfo.UseShellExecute = false;
        mplayer.StartInfo.RedirectStandardInput = true;
        mplayer.StartInfo.FileName = "VideoStreamRecv.bash";
        mplayer.StartInfo.Arguments = PanelID.ToString();
    }

    public void Start()
    {
        mplayer.Start();
    }

    public void End()
    {
        mplayer.Kill();
        Process.Start("pkill mplayer");
    }
}
编译项目并将所有二进制文件和
VideoStreamRecv.bash
复制到与二进制文件相同的目录中,并将其复制到Raspberry Pi中

使用以下命令安装mono for Raspberry Pi:

sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF
echo "deb http://download.mono-project.com/repo/debian raspbianstretch main" | sudo tee /etc/apt/sources.list.d/mono-official.list
sudo apt-get update
sudo apt-get install mono-devel --yes --allow-unauthenticated
使用此命令(与@CoreMeltdown相同)在Raspberry Pi上启动连接相机的相机流

在接收器Raspberry Pi(带有已编译二进制文件的接收器)上,打开终端,转到带有二进制文件的目录并执行:

mono MplayerFrontEnd.exe # MplayerFrontEnd is the name of my project, use your own name here.
下面是它的样子:

戴夫:D

public partial class Base : Form
{
    private MPlayer Player;
    private StreamWriter PlayerInput;
    public Base()
    {
        InitializeComponent();
    }

    private void Base_Load(object sender, EventArgs e)
    {
        Player = new MPlayer((int)Video.Handle);
        Player.Start();
    }

    private void Stop_Click(object sender, EventArgs e)
    {
        Player.End();
    }
}
class MPlayer
{
    Process mplayer;

    public MPlayer(int PanelID)
    {
        mplayer = new Process();
        mplayer.StartInfo.UseShellExecute = false;
        mplayer.StartInfo.RedirectStandardInput = true;
        mplayer.StartInfo.FileName = "VideoStreamRecv.bash";
        mplayer.StartInfo.Arguments = PanelID.ToString();
    }

    public void Start()
    {
        mplayer.Start();
    }

    public void End()
    {
        mplayer.Kill();
        Process.Start("pkill mplayer");
    }
}
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF
echo "deb http://download.mono-project.com/repo/debian raspbianstretch main" | sudo tee /etc/apt/sources.list.d/mono-official.list
sudo apt-get update
sudo apt-get install mono-devel --yes --allow-unauthenticated
raspivid --width 400 --height 300 -t 9999999 --framerate 25 --output - | nc -l 5000
mono MplayerFrontEnd.exe # MplayerFrontEnd is the name of my project, use your own name here.