gpt4 book ai didi

c# - 在 C# 应用程序中播放 Raspberry Pi h264 流

转载 作者:太空狗 更新时间:2023-10-29 21:44:35 24 4
gpt4 key购买 nike

我有一个带有专用摄像头的 Raspberry Pi 板,只能以 h264 格式录制视频。我正在寻找在 c# Windows 窗体应用程序中实时流式传输和播放录制视频的最佳方法(例如,延迟不到 1 秒)。附加要求是在显示之前可以轻松处理此类流,例如搜索图像上的对象。

我尝试过的东西:

- raspi 上的 VLC 服务器和 c# 表单应用程序中的 VLC 控制 <- 简单的解决方案,使用 RTSP,但有一个严重的缺陷,即图像显示延迟约 3 秒。我无法通过缓冲区大小/选项等修复它。

- 使用 nc 在 raspi 上创建套接字,在 c# 中接收原始 h264 数据并将其传递给 mplayer 前端 <- 如果我只是启动 raspivid | nc 和笔记本电脑上的 nc | mplayer,我得到了我想要的结果,我得到的视频几乎是实时的,但是当我尝试在 c# 中创建 mplayer 前端并模拟 nc.exe 时,问题就出现了。也许我错误地传递了 h264 数据(只需将它们写入标准输入)或其他原因。

- 使用 https://github.com/cisco/openh264 <- 我编译了所有内容,但我什至无法解码我用 h264dec.exe 在 raspi 上录制的示例 vid.h264,更不用说在 c# 中使用它了。

h264dec.exe vid.h264 out.yuv

这会产生 0 字节的 out.yuv 文件,同时:

h264dec.exe  vid.h264

给我错误信息:“配置文件中没有指定输入文件。”

- ffmpeg <- 我在 c# 应用程序中实现了 ffplay.exe 播放,但是缺乏简单的截屏方法等阻碍了我进一步研究和开发。

我什至不确定我是否正确地接近了这个主题,所以我非常感谢我能得到的每一条建议。

编辑这是我试图在 c# 中实现的“工作”解决方案

raspivid --width 400 --height 300 -t 9999999 --framerate 25 --output - | nc -l 5884

nc ip_addr 5884 | mplayer -nosound -fps 100 -demuxer +h264es -cache 1024 -

这里的关键是 FPS 100,因为这样 mplayer 就会跳过延迟并以正常速度播放它立即接收到的视频。这里的问题是我不知道如何通过 c# 将视频数据从套接字传递到 mplayer,因为我猜它不是通过标准输入完成的(已经尝试过)。

最佳答案

好的,实际上我设法解决了这个问题:

就像我之前说的那样 -fps 120 选项可以让播放器跳过缓冲区中的内容并在收到流后立即播放。 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();
}
}

后台 worker 从套接字读取内容:

    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);
}
}

运行在树莓派上的脚本。 Portnumber 是 rasp 监听的端口号。

#!/bin/bash

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

关于c# - 在 C# 应用程序中播放 Raspberry Pi h264 流,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24467686/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com