在将 IP 摄像机与 C# 应用程序连接时,我在 Aforge/Samples/Player 中找到了简单的播放器。它只需要修改 ip 字符串,所以我添加了我的admin:admin@192.168.1.239:81/videostream.cgi?rate=11来获取 MJPEG 视频流。编译时出现错误,因为远程服务器返回错误 (401) 未经授权。Andre Kirillow 在 MJPEGstream.cs 文件中提到一些相机会产生 HTTP 标头,它不严格符合标准,导致 .NET 异常。为了避免这种异常,应该设置 httpWebRequest 的 useUnsafeHeaderParsing 配置选项,可以使用应用程序配置文件来完成。
<configuration>
<system.net>
<settings>
<httpWebRequest useUnsafeHeaderParsing="true" />
</settings>
</system.net>
</configuration>
好吧,正如Dinis Cruz所建议的,有两种方法可以做到这一点。我使用上面的代码添加了 .config 文件,并且还以编程方式进行了操作,但同样的错误仍然存在。Player程序编码是
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using AForge.Video;
using AForge.Video.DirectShow;
using System.Reflection;
using System.Net.Configuration;
using System.Net;
namespace Player
{
public partial class MainForm : Form
{
private Stopwatch stopWatch = null;
// Class constructor
public MainForm( )
{
InitializeComponent( );
}
private void MainForm_FormClosing( object sender, FormClosingEventArgs e )
{
CloseCurrentVideoSource( );
}
// "Exit" menu item clicked
private void exitToolStripMenuItem_Click( object sender, EventArgs e )
{
this.Close( );
}
// Open local video capture device
private void localVideoCaptureDeviceToolStripMenuItem_Click( object sender, EventArgs e )
{
VideoCaptureDeviceForm form = new VideoCaptureDeviceForm( );
if ( form.ShowDialog( this ) == DialogResult.OK )
{
// create video source
VideoCaptureDevice videoSource = form.VideoDevice;
// open it
OpenVideoSource( videoSource );
}
}
// Open video file using DirectShow
private void openVideofileusingDirectShowToolStripMenuItem_Click( object sender, EventArgs e )
{
if ( openFileDialog.ShowDialog( ) == DialogResult.OK )
{
// create video source
FileVideoSource fileSource = new FileVideoSource( openFileDialog.FileName );
// open it
OpenVideoSource( fileSource );
}
}
// Open JPEG URL
private void openJPEGURLToolStripMenuItem_Click( object sender, EventArgs e )
{
URLForm form = new URLForm( );
form.Description = "Enter URL of an updating JPEG from a web camera:";
form.URLs = new string[]
{
"http://195.243.185.195/axis-cgi/jpg/image.cgi?camera=1",
};
if ( form.ShowDialog( this ) == DialogResult.OK )
{
// create video source
JPEGStream jpegSource = new JPEGStream( form.URL );
// open it
OpenVideoSource( jpegSource );
}
}
// Open MJPEG URL
private void openMJPEGURLToolStripMenuItem_Click( object sender, EventArgs e )
{
URLForm form = new URLForm( );
form.Description = "Enter URL of an MJPEG video stream:";
form.URLs = new string[]
{
"http://admin@192.168.1.239:81/videostream.cgi?rate=11",
"mjpegSource by mobby"
};
if ( form.ShowDialog( this ) == DialogResult.OK )
{
// create video source
MJPEGStream mjpegSource = new MJPEGStream( form.URL );
// open it
OpenVideoSource( mjpegSource );
}
}
// Open video source
private void OpenVideoSource( IVideoSource source )
{
// set busy cursor
this.Cursor = Cursors.WaitCursor;
// stop current video source
//CloseCurrentVideoSource( );
// start new video source
videoSourcePlayer.VideoSource = source;
videoSourcePlayer.Start( );
// reset stop watch
stopWatch = null;
// start timer
timer.Start( );
this.Cursor = Cursors.Default;
}
// Close video source if it is running
private void CloseCurrentVideoSource( )
{
if ( videoSourcePlayer.VideoSource != null )
{
videoSourcePlayer.SignalToStop( );
// wait ~ 3 seconds
for ( int i = 0; i < 30; i++ )
{
if ( !videoSourcePlayer.IsRunning )
break;
System.Threading.Thread.Sleep( 100 );
}
if ( videoSourcePlayer.IsRunning )
{
videoSourcePlayer.Stop( );
}
videoSourcePlayer.VideoSource = null;
}
}
// New frame received by the player
private void videoSourcePlayer_NewFrame( object sender, ref Bitmap image )
{
DateTime now = DateTime.Now;
Graphics g = Graphics.FromImage( image );
// paint current time
SolidBrush brush = new SolidBrush( Color.Red );
g.DrawString( now.ToString( ), this.Font, brush, new PointF( 5, 5 ) );
brush.Dispose( );
g.Dispose( );
}
// On timer event - gather statistics
private void timer_Tick( object sender, EventArgs e )
{
IVideoSource videoSource = videoSourcePlayer.VideoSource;
if ( videoSource != null )
{
// get number of frames since the last timer tick
int framesReceived = videoSource.FramesReceived;
if ( stopWatch == null )
{
stopWatch = new Stopwatch( );
stopWatch.Start( );
}
else
{
stopWatch.Stop( );
float fps = 1000.0f * framesReceived / stopWatch.ElapsedMilliseconds;
fpsLabel.Text = fps.ToString( "F2" ) + " fps";
stopWatch.Reset( );
stopWatch.Start( );
}
}
}
public static bool SetAllowUnsafeHeaderParsing20()
{
//Get the assembly that contains the internal class
Assembly aNetAssembly = Assembly.GetAssembly(typeof(System.Net.Configuration.SettingsSection));
if (aNetAssembly != null)
{
//Use the assembly in order to get the internal type for the internal class
Type aSettingsType = aNetAssembly.GetType("System.Net.Configuration.SettingsSectionInternal");
if (aSettingsType != null)
{
//Use the internal static property to get an instance of the internal settings class.
//If the static instance isn't created allready the property will create it for us.
object anInstance = aSettingsType.InvokeMember("Section",
BindingFlags.Static | BindingFlags.GetProperty | BindingFlags.NonPublic, null, null, new object[] { });
if (anInstance != null)
{
//Locate the private bool field that tells the framework is unsafe header parsing should be allowed or not
FieldInfo aUseUnsafeHeaderParsing = aSettingsType.GetField("useUnsafeHeaderParsing", BindingFlags.NonPublic | BindingFlags.Instance);
if (aUseUnsafeHeaderParsing != null)
{
aUseUnsafeHeaderParsing.SetValue(anInstance, true);
return true;
}
}
}
}
return false;
}
}
}
从谷歌我添加了一些开放的 ip 摄像头,那里的视频流被捕获并且工作正常,但我的摄像头返回错误 401。然后我使用了Sean Tearney最近制作的 ISPY 软件,该软件使用相同的 Aforge 库构建,它捕获了我的摄像头的视频流:页。现在我不知道简单播放器的编码有什么问题。如果有人可以帮助我从相机获取视频流,请多多关照。谢谢