c#中的视频通话

时间:2011-01-13 13:21:27

标签: c# wpf silverlight streaming directshow

我想向Skype提出类似的应用程序,主要问题是使用视频和音频。第一个问题是如何获取视频的字节数组(具体来说,我需要获取代表视频的字节,以便我可以通过互联网发送它们),以及音频相同。第二个问题是播放来自另一台计算机的字节。 我一直在考虑在WPF中这样做。我是WPF的新手(我已经练习了一点,并制作了几个程序,其中一个是基本的聊天程序)。我这样做是为了练习,我想尽可能自己编码,服务器,客户端,数据传输等等...... 我一直在互联网上搜索,在我看来只有一个解决方案是好的,或者更好的说可行,就是使用DirectShow。

只是补充一下,我知道Silverlight支持相机和麦克风,我已经尝试过了(实际上,我试图在WPF项目中托管一个带有Silverlight项目的HTML页面,其中有webbrowser控件,我我成功地从我的网络摄像头显示视频,但我不知道如何获得代表视频的字节。

这可能与WPF或silverlight有关吗? 我非常感谢建议任何解决方案,建议或有用的链接。

6 个答案:

答案 0 :(得分:1)

我无法与WPF或Silverlight交谈,但我在DirectShow中已经完成了这项工作,这对我来说很痛苦。 如果你想使用.NET,那就是一个名为DirectShow.NET的开源包装器,它可以帮助很多,而且它仍然很麻烦。

微软在DirectShow和整个过滤器图形方面做得很好,但是他们不久前放弃了这些球并且多年来没有更新它。

我建议寻找不同的技术(尽管它可能位于DirectShow上),我很想听听你的发现。

答案 1 :(得分:1)

使用DirectShow过滤器图形,您可以直接从输入设备(如摄像头和麦克风)访问图像和音频缓冲区作为字节数组,逐个样本。您将能够直接操作数据,选择编码或压缩格式(使用特定过滤器),并控制数据速率和同步。

但是:

  • 如果你对这个环境完全陌生,它将是 hard 。另外,我知道它可以很好地与C ++一起工作,但我从来没有用C#编写任何Directshow应用程序。 (您可能希望这样:CodeProject Tutorials,MSDN DirectShow主题和使用 graphedit 的测试

  • 通过网络流媒体并使用Directshow接收它并非易事,而且可能非常痛苦。网络渲染器和网络源过滤器可用,但在我看来总是很难使用。根据您的视频格式(H264,MPEG,MJPEG ...)和网络协议(RTSP,简单的旧简单UDP ...)选择,您可能最终必须编写自己的流/源过滤器,这很难,耗费时间。

尽管如此,这是可行的,如果你的主要目标是练习编码,那么为什么不呢!

(从未使用WPF,也许它实际上更简单!)

答案 2 :(得分:0)

对所有对此感兴趣的人。 首先要说的是我一直在阅读有关directshow和媒体基础的文章。只需提一下,directshow程序只能用C ++编写,通过COM模型,您可以将directshow程序与其他可视语言一起使用。媒体基金似乎非常有前景,但它只能在Vista和Win 7上运行。 我一直在阅读有关directshow.net库的内容,并且发现了一些似乎可以解决我的问题的方法:)在这个页面上link你可以找到使用directshow.net库的例子,并且有一个例子命名 DxWebCam ,它关于我想做的事情:从视频拍照和通过互联网发送到另一个客户端。我将尝试编写简单的示例,并让您了解我的进度。 :)

答案 3 :(得分:0)

亲爱的, 花了几个小时来弄清楚DirectShow是如何工作的,我没有找到任何简单的例子如何播放媒体,没有任何修改只是播放。但是,我最终设法做到了这一点。我现在简要介绍一下DirectShow的工作原理。要播放任何内容(音频或视频),首先要打开它们,解压缩它们(因为大多数都使用某种压缩,以节省磁盘空间),然后将它们发送到将重现它们的设备。当然,根据媒体格式等,可以有更多的步骤要做,但这是对系统的最简单的解释。所有这些任务都由过滤器完成,一组连接的过滤器生成过滤器图形。这可能很难理解,但我认为在看了this示例之后,您将会对此有更清晰的了解。 并且说对于某些格式,您不必执行所有操作,因为过滤器图形可以为您完成。它创建并连接所有需要的过滤器,并为您运行它们。

我忘了提到我使用的是DirectShow.net库,它是SourceFourge打开的项目,它就像是微软的DirectShow的某种包装器。这是非常有用的,因为最初DirectShow仅限于在C ++中使用,但是使用DirectShow.net,您可以将它与C#,VB一起使用,并且正如他们所说的“理论上使用任何.net语言”。 DirectShow.net的原理与DirectShow相同,因此学习两者都从同一个网页开始:Microsoft web page。要在项目中使用DirectShow.net,只需从SourceForge open project下载库,添加对它的引用并添加using DirectShowLib;即可。并且,访问他们的论坛。最后,请记住,您从微软网页学习原理,或者说事情是如何工作的,但是使用DirectShow.net可以从样本中学习,或者说如何使用工具来执行不同的任务。您可以从此link下载样本和库 以下是播放mp3文件的示例代码:

  class Example{
        ///....
        IGraphBuilder gb, gb1;
        IMediaControl mc, mc1;
        IVideoWindow vw;
        private void button1_Click(object sender, RoutedEventArgs e)
        {
            gb = (IGraphBuilder) new FilterGraph();
            mc = (IMediaControl)gb; 
            //mc = gb as IMediaControl;//you can use this way instead of casting
            mc.RenderFile("C:\\test.mp3");
            mc.Run();

            gb1 = (IGraphBuilder)new FilterGraph();
            mc1 = (IMediaControl)gb1;
            vw = (IVideoWindow)gb1;
            vw.SetWindowPosition(0, 0, 320, 240);
            mc1.RenderFile("C:\\test.avi");
            mc1.Run();

         }

     }

您可以在计算机上的任何位置指定任何文件,但我这样做是为了保持简单。这些是播放文件的最简单示例,并添加您需要了解DirectShow如何工作的任何其他控件。

希望这会有所帮助。 :)

答案 4 :(得分:0)

有些人建议我尝试用silverlight做程序,所以我一直试一试。我设法将相机连接到我的应用程序,拍摄快照并将其显示为视频,并且它非常酷(单独的线程负责拍摄快照。它调用CaptureImageAsync并在信号量上阻塞,直到捕获完成。在解除阻塞后显示它捕获图像并睡眠100毫秒(这是可选的,它实际上是帧速率 - 较小的数字意味着更好的视频,更大的数字 - 好吧,它不会是一个视频,它将像图片幻灯片)。如果有人对这里的代码发布感兴趣我会发布我的代码。)

我正在处理的问题是将图片转换为jpeg(或其他格式),因为原始图片使用大约300KB,而且不易察觉,因为你的第二张照片至少有5张,所以需要1,5张MBytes上传连接:D我正在尝试使用imagetools,如果有任何进展,我会告诉你。

答案 5 :(得分:0)

对所有对此主题感兴趣的人,

在花了数小时和数小时搜索互联网后,我设法找到了一个应该有效的解决方案。使用Silverlight,我会捕获,将它们调整为160x120(或更低),然后使用图像工具转换它们。一个负责拍照,开始捕捉的线程,当它完成时(捕获是异步的,所以你需要使用信号量)它会睡眠200ms;这几乎相当于每秒5帧。我正在做所有这些因为我的上传带宽很慢,大约每秒16千字节,所以我必须尽可能多地压缩一帧。结果是低详细的图片,但如果你使用100x100矩形进行查看,它也不算太糟糕。我还没有尝试过互联网,但是,正如我所说,它应该有效。我也尝试使用压缩方法,如果可能的话,再压缩图片,但我不知道如何使用该类(有些东西不能正常工作),所以再把它留下来了。现在我只想让它发挥作用,而后者我会努力提高性能。 哦,还有一件事,我还必须解决音频传输问题,这需要很多工作。 所以,听听后者。