我试图让我的 Parrot AR Drone 2.0 在 Windows 机器上工作。
我有一个简单的 C# 应用程序来控制它 - 但现在我想要我的应用程序中的视频流。
如果我执行ffplay tcp://192.168.1.1:5555
它会连接到视频流并显示一个带有视频的窗口。
如何在我的应用程序中获取此视频?比如,一个简单的“框架”或“图像”填充了这些内容?
我从来没有在 C# 上工作过那么多,所以任何帮助都会很棒。
您可以启动该ffplay
过程,然后 PInvokeSetParent
将播放器窗口放置在您的表单MoveWindow
中并定位它。
为此,您需要定义以下内容。
[DllImport("user32.dll", SetLastError = true)]
private static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);
[DllImport("user32.dll")]
private static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
然后你可以像这样使用这两种本机方法。
// start ffplay
var ffplay = new Process
{
StartInfo =
{
FileName = "ffplay",
Arguments = "tcp://192.168.1.1:5555",
// hides the command window
CreateNoWindow = true,
// redirect input, output, and error streams..
RedirectStandardError = true,
RedirectStandardOutput = true,
UseShellExecute = false
}
};
ffplay.EnableRaisingEvents = true;
ffplay.OutputDataReceived += (o, e) => Debug.WriteLine(e.Data ?? "NULL", "ffplay");
ffplay.ErrorDataReceived += (o, e) => Debug.WriteLine(e.Data ?? "NULL", "ffplay");
ffplay.Exited += (o, e) => Debug.WriteLine("Exited", "ffplay");
ffplay.Start();
Thread.Sleep(200); // you need to wait/check the process started, then...
// child, new parent
// make 'this' the parent of ffmpeg (presuming you are in scope of a Form or Control)
SetParent(ffplay.MainWindowHandle, this.Handle);
// window, x, y, width, height, repaint
// move the ffplayer window to the top-left corner and set the size to 320x280
MoveWindow(ffplay.MainWindowHandle, 0, 0, 320, 280, true);
该ffplay
过程的标准输出,您通常在命令窗口中看到的文本是通过ErrorDataReceived
. 将 设置-loglevel
为类似于fatal
传递给 ffplay 的参数中的内容可以减少引发的事件数量并允许您仅处理真正的失败。
您是否尝试过使用媒体播放器进行流式传输?只需从表单的工具箱中添加控件,然后将以下代码添加到您的 form.cs
private void Form1_Load(object sender, EventArgs e)
{
axWindowsMediaPlayer1.URL = "your URL";
}
}
以下链接中的详细信息
http://msdn.microsoft.com/en-us/library/bb383953%28v=vs.90%29.aspx
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Diagnostics;
using System.Threading;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Drawing.Text;
using System.Text.RegularExpressions;
using System.Configuration;
using Microsoft.Win32;
using System.Windows.Forms.VisualStyles;
namespace FfplayTest
{
public partial class Form1 : Form
{
[DllImport("user32.dll", SetLastError = true)]
private static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);
[DllImport("user32.dll")]
private static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
[DllImport("user32.dll", EntryPoint = "SetWindowPos")]
public static extern IntPtr SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int x, int Y, int cx, int cy, int wFlags);
public Form1()
{
InitializeComponent();
Application.EnableVisualStyles();
this.DoubleBuffered = true;
}
private void Form1_Load(object sender, EventArgs e)
{
}
public Process ffplay = new Process();
private void xxxFFplay()
{
ffplay.StartInfo.FileName = "ffplay.exe";
string _argString = "-fflags nobuffer \"rtsp://admin:admin@192.168.0.163/live0.264\" -x 640 -y 480";
string _newArgString = _argString.Replace("\",\"", ";");
ffplay.StartInfo.Arguments = _newArgString;
ffplay.StartInfo.CreateNoWindow = true;
ffplay.StartInfo.RedirectStandardOutput = true;
ffplay.StartInfo.UseShellExecute = false;
ffplay.EnableRaisingEvents = true;
ffplay.OutputDataReceived += (o, e) => Debug.WriteLine(e.Data ?? "NULL", "ffplay");
ffplay.ErrorDataReceived += (o, e) => Debug.WriteLine(e.Data ?? "NULL", "ffplay");
ffplay.Exited += (o, e) => Debug.WriteLine("Exited", "ffplay");
ffplay.Start();
IntPtr intPtr = ffplay.MainWindowHandle;
Thread.Sleep(200); // you need to wait/check the process started, then...
// child, new parent
// make 'this' the parent of ffmpeg (presuming you are in scope of a Form or Control)
SetParent(ffplay.MainWindowHandle, this.Handle);
// window, x, y, width, height, repaint
// move the ffplayer window to the top-left corner and set the size to 320x280
MoveWindow(ffplay.MainWindowHandle, 0, 0, 320, 280, true);
}
private void button1_Click(object sender, EventArgs e)
{
xxxFFplay();
}
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
try { ffplay.Kill(); }
catch { }
}
}
}
我的代码是这样的,它如何加载 ffplay 但不要移入面板或不将其定位到给定