读书人

贴源码-网络视频传输相关

发布时间: 2012-05-10 16:02:39 作者: rapoo

贴源码求助-网络视频传输相关
以下代码VS2008SP1下编译通过
WinXP与WIN7运行通过
运行状况描述:1.通过Encoder对AVI格式视频文件进行编码广播,以Media Player和本人自写播放界面本机连接播放,连接时间大约3秒,声音与视频同步状况良好,其他操作状况良好,直观印象无延迟。
2.通过Encoder采集普通摄像头视频源与耳麦话筒音频编码广播,本机以MediaPlayer连接时间大约7秒,音频与视频同步状况良好,但它们同步地延迟于实时15秒左右,其他操作状况良好
测试硬环境描述:盈通G41V主板集成声卡,集成显卡+E5300CPU 本机发送,本机接收

猜测:延迟主要瓶颈在于音频视频采集后的编码过程,由于纯软环境编码造成大量时间浪费

拟采用解决办法:调出Encoder数据缓冲区音频和视频元数据,对其进行相关简单处理后直接发送至接收端再进行显示处理,以网络带宽为代价,避免掉时间浪费。懒人的办法,LOL。

问题:Encoder的数据缓冲区在哪儿。翻遍了SDK文档,没找到相关文字。或者是因为本人E文水平太烂了吧,呵呵。

希望路过的朋友能给指点迷津.

邮件:cikemomoloveme@yahoo.cn



using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
//添加窗口管理程序集引用
using System.Windows.Forms;
using System.Drawing;
//添加线程管理程序集引用
using System.Threading;
//添加网络传输及IO程序集引用
using System.Net;
using System.IO;
//添加视频音频编码解码程序集引用
using Microsoft.Expression.Encoder;
using Microsoft.Expression.Encoder.Live;



namespace _Home
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
private System.Windows.Forms.NotifyIcon myIcon;
private System.ComponentModel.IContainer components;


public MainWindow()
{


InitializeComponent();
//设置容器
this.components = new System.ComponentModel.Container();


//定义托盘图标
this.myIcon = new NotifyIcon(this.components);
//注意路径设置
string iconPath = Directory.GetCurrentDirectory() + "/Image/Icon_xp_19.ico";
myIcon.Icon = new Icon(iconPath );

//定义托盘菜单
myIcon.ContextMenu = new System.Windows.Forms.ContextMenu();
//定义托盘菜单项
System.Windows.Forms.MenuItem ItemF = new System.Windows.Forms.MenuItem();
System.Windows.Forms.MenuItem ItemS = new System.Windows.Forms.MenuItem();
System.Windows.Forms.MenuItem ItemA = new System.Windows.Forms.MenuItem();
System.Windows.Forms.MenuItem ItemB = new System.Windows.Forms.MenuItem();

ItemF.Text = "开始监控";
ItemS.Text = "后台监控";
ItemA.Text = "重写证书";
ItemB.Text = "退出监控";
//添加菜单项到菜单
myIcon.ContextMenu.MenuItems.Add(0, ItemF);
myIcon.ContextMenu.MenuItems.Add(1, ItemS);
myIcon.ContextMenu.MenuItems.Add(2, ItemA);
myIcon.ContextMenu.MenuItems.Add(3, ItemB);
//定义菜单项事件处理程序
ItemF.Click += new EventHandler(ItemF_Click);
ItemS.Click += new EventHandler(ItemS_Click);
ItemA.Click += new EventHandler(ItemA_Click);
ItemB.Click += new EventHandler(ItemB_Click);
//显示托盘图标及提示文字
myIcon.Visible = true ;
myIcon.Text = "XXX";
//定义托盘图标事件处理程序
myIcon.Click += new EventHandler(myIcon_Click);
myIcon.DoubleClick += new EventHandler(myIcon_DoubleClick);
//禁止任务栏显示
this.ShowInTaskbar = true ;




//显示IP
ProofClass myIPclass = new ProofClass();
this.title=myIPclass.titleIP();




}

//以下代码段创建线程
Thread EncodThread;

theEncoderTread Encoder = new theEncoderTread();

void ItemB_Click(object sender, EventArgs e)
{
this.Close();
}

void ItemA_Click(object sender, EventArgs e)
{

}

void ItemS_Click(object sender, EventArgs e)
{

}

void ItemF_Click(object sender, EventArgs e)
{
this.Show();
Encoder.intEncod();
EncodThread = new Thread(Encoder.startEncod);

EncodThread.Start();

}



void myIcon_DoubleClick(object sender, EventArgs e)
{
this.Activate();
this.Show();
}

void myIcon_Click(object sender, EventArgs e)
{
this.Activate();


}
public void menuItem_Click(object Sender, EventArgs e)
{



}

private void Window_SizeChanged(object sender, SizeChangedEventArgs e)
{




}
//定义窗口状态事件处理程序
private void Window_StateChanged(object sender, EventArgs e)
{ //判断窗口改变方式,并作出相应处理
switch (this.WindowState)
{
case (WindowState.Maximized):
{
//注意:如果先隐藏窗口,则改变窗口状态的代码不起作用
this.WindowState = WindowState.Normal;
this.Hide();
break;
}
case WindowState.Normal:
{
this.Hide();
break;
}
case WindowState.Minimized:
{
this.WindowState = WindowState.Normal;
this.Hide();
break;
}
default:
{
break;
}

}
}
//窗口关闭,销毁托盘图标
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
myIcon.Dispose();
Encoder.EndEncod();



}

private void border1_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
this.DragMove();
}

}
public class theEncoderTread
{
public LiveJob myJob = new LiveJob();




LiveDevice theAudio;
LiveDevice theVedio;
LiveDeviceSource theLiveDevice;

WindowsMediaBroadcastOutputFormat myOutFormat = new WindowsMediaBroadcastOutputFormat();




//初始化监控环境,添加设备源,此处仅考虑单路监控情况,且假定所需设备均已连接,对于其他情况未做处理
public void intEncod()
{


theAudio =myJob .AudioDevices [0];
theVedio =myJob .VideoDevices [0];
theLiveDevice = myJob.AddDeviceSource(theVedio ,theAudio );

//定义广播规则
myOutFormat.BroadcastPort = 8080;//广播端口
myOutFormat.MaximumNumberOfConnections = 2;//最大连接数

myJob.OutputFormat = myOutFormat;


}
public void startEncod()
{
myJob.ActivateSource(theLiveDevice );


myJob.StartEncoding();
}

public void EndEncod()
{
myJob.StopEncoding();
myJob.Dispose();


}
}
//此类主要用于连接证书的创建
public class ProofClass
{
string Name="Proof.PRO";//默认证书文件名
string ProofPath = Directory.GetCurrentDirectory();
SaveFileDialog theSave = new SaveFileDialog();
StreamWriter myWriter;

string hostName;
string hostIP;

public void SaveProof()
{
string saveString;
theSave.Filter = "(证书文件)*.cre|*.cre";
theSave.ShowDialog();
if (theSave.FileName != "")
{
saveString = theSave.FileName;
}
else
{
saveString = ProofPath +Name ;
}
myWriter = new StreamWriter(saveString);

//此段对本机IP进行查询
hostName = Dns.GetHostName();
hostIP=new IPAddress (Dns .GetHostByName (hostName ).AddressList [0].Address ).ToString ();
myWriter.WriteLine(hostIP );
myWriter.Close();
}

//为方便测试,改写窗口标题为IP地址
public string titleIP()

{
hostName = Dns.GetHostName();
hostIP = new IPAddress(Dns.GetHostByName(hostName).AddressList[0].Address).ToString();
return hostIP;

}


}

}



[解决办法]
DirectShow有专门的接口,可以查询硬件设备的,具体是哪一个接口,你得查一下资料的,我之前做的项目代码不在身边,要不然就帮你找一找了。

读书人网 >C#

热点推荐