在C#应用程序中播放树莓皮h264流
我有一个覆盆子Pi板,带有专用摄像机,只能在h264中录制视频。我正在寻找在c#windows窗体应用程序中实时流式传输和播放录制视频的最佳方法(例如,延迟不到1秒)。另外的要求是,在显示之前可以容易地处理这样的流,例如用于搜索图像上的对象 我试过的东西:在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嵌套的面板的句柄
-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.