ROS交流群
ROS Group 产品服务
Product Service 开源代码库
Github 官网
Official website 技术交流
Technological exchanges 激光雷达
LIDAR ROS教程
ROS Tourials 深度学习
Deep Learning 机器视觉
Computer Vision
ROS Group 产品服务
Product Service 开源代码库
Github 官网
Official website 技术交流
Technological exchanges 激光雷达
LIDAR ROS教程
ROS Tourials 深度学习
Deep Learning 机器视觉
Computer Vision
利用网络传输系统的声音
-
为什么要做这件事呢,因为我的电脑耳机插孔不太好使。插上耳机后声音经常的是左边有声音右边没有这样子。在玩游戏的时候这样太不爽了。 而且像VNC这种远程软件是没有声音的,用起来也很不舒服。所以我很需要一个能够远程传输声音的软件。现在有了代码在Github上,虽然还有一些问题,但是基本上能用了,而且还是跨平台的。
下面说一下具体的实现方法。
基本的流程就是从声卡获取到声音信息然后写入到http流里面。这样通过浏览器就可以听到系统的声音了。程序用C#写的,我很喜欢这种语言。声音的获取和转码处理方面用的是一个叫做cscore的库。把http流传给cscore里面对应的API就可以了。但是由于HttpResponse的流是只写的,而cscore里面转码需要的输出流是可读可写的,所以这里要修改cscore的源代码才行。贴上比较关键的代码吧
在C# web api里面如何处理流using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Net.Http; using System.Net.Http.Headers; using System.Text; using System.Threading.Tasks; using System.Web.Http; namespace RemoteAudio.Controllers { public class AudioController : ApiController { [Route("audio")] [HttpGet] public HttpResponseMessage Get() { var response = Request.CreateResponse(); response.Content = new PushStreamContent((Action<Stream, HttpContent, TransportContext>)(AudioServer.getInstance().WriteToStream), new MediaTypeHeaderValue("audio/mpeg")); response.Headers.Add("Cache-Control", "no-cache"); return response; } //[Route("web")] //[HttpGet] //public HttpResponseMessage Get() //{ // var response = Request.CreateResponse(); // return response; //} } }
关键在于以上代码中的
PushStreamContent
方法。在传进去的回调函数中第一个参数就是HttpResponse的流,把这个流传给修改后的cscore api就可以了。using (var encoder = MediaFoundationEncoder.CreateMP3Encoder(capture.WaveFormat, httpStream, 48000)) { capture.DataAvailable += (s, e) => { encoder.Write(e.Data, e.Offset, e.ByteCount); }; }
用起来也是很简单的。
现有的问题
- 会有大约三秒的延时。用来听歌之类的是没问题,但是用来玩游戏,绝对不能忍。个人感觉是编码函数里面做了buffer。以后要进行改进。还有就是浏览器按下暂停键后是用浏览器的缓存继续播放,这个和服务器正在传输的流之间的时间差就会增加。这个声音同步应该在浏览器中用js实现呢还是应该在服务器通过一些手段实现呢?还没想好。
- 没有回收httpResponse stream。这个也是要改进的地方,不然会内存泄露。