导航

    蓝鲸ROS机器人论坛

    • 注册
    • 登录
    • 搜索
    • 版块
    • 话题
    • 热门
    ROS交流群
    ROS Group
    产品服务
    Product Service
    开源代码库
    Github
    官网
    Official website
    技术交流
    Technological exchanges
    激光雷达
    LIDAR
    ROS教程
    ROS Tourials
    深度学习
    Deep Learning
    机器视觉
    Computer Vision

    利用网络传输系统的声音

    技术交流
    1
    1
    3303
    正在加载更多帖子
    • 从旧到新
    • 从新到旧
    • 最多赞同
    回复
    • 在新帖中回复
    登录后回复
    此主题已被删除。只有拥有主题管理权限的用户可以查看。
    • weijiz
      weijiz 最后由 编辑

      为什么要做这件事呢,因为我的电脑耳机插孔不太好使😭。插上耳机后声音经常的是左边有声音右边没有这样子。在玩游戏的时候这样太不爽了。 而且像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);
                          };
       }
      

      用起来也是很简单的。

      现有的问题

      1. 会有大约三秒的延时。用来听歌之类的是没问题,但是用来玩游戏,绝对不能忍。个人感觉是编码函数里面做了buffer。以后要进行改进。还有就是浏览器按下暂停键后是用浏览器的缓存继续播放,这个和服务器正在传输的流之间的时间差就会增加。这个声音同步应该在浏览器中用js实现呢还是应该在服务器通过一些手段实现呢?还没想好。
      2. 没有回收httpResponse stream。这个也是要改进的地方,不然会内存泄露。
      1 条回复 最后回复 回复 引用 0
      • 1 / 1
      • First post
        Last post
      Copyright © 2015-2023 BlueWhale community