直播(Socket)-如何同步音频和视频?

发布于 2024-09-29 06:17:52 字数 97 浏览 6 评论 0原文

1- 哪一种更适合用于流媒体视频? TCP 或 UDP 套接字以及为什么?

2-直播时,音频和视频分别来自服务器,那么如何确保我显示的视频和设备上播放的音频同步?

1- Which one is better to use for streaming video ? TCP or UDP socket and why?

2- While streaming live, audio and video are coming from the server separately, so how can i make sure that the video i display and the audio I play on the device are in sync?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

醉梦枕江山 2024-10-06 06:17:52

我不久前编写了一个语音聊天应用程序,TCP 是不可能的,如果您正在寻找近实时数据流,UDP 多播实际上是唯一的方法。不过,通过 UDP 进行流传输有两个主要问题:

  1. 丢包。就音频而言,这是一个非常简单的修复。通常,丢弃的数据包不会产生听得见的差异(数据包是单独解压缩的)。然而,在处理视频时,特别是在视频被压缩的情况下(通常是压缩的),找出确保网络稳健性的适当传输协议至少可以说是一项艰巨的任务,特别是如果您从头开始这样做。视频帧被分成不同的数据包。弄清楚当这些数据包丢失时该怎么办是很困难的。
  2. 音频和视频之间的同步。这是一个非常棘手的问题,我建议阅读 RTSP(实时流协议)等协议。这不是一件容易的事,但这里有一些介绍性信息:http://www.cs。 columbia.edu/~hgs/rtsp/ - 有时它是通过发送单独的同步数据包(某些协议通过 TCP 发送这些数据包)来完成的,告诉播放器声音应如何与视频匹配。

I wrote a voice chat application a while ago and TCP was out of the question, UDP multicasting is really the only way to go if you're looking for near-realtime data flow. There's two main issues with streaming stuff over UDP though:

  1. The dropped packets. In the case of audio, it's a pretty easy fix. Usually the dropped packets won't make an audible difference (the packets are decompressed individually). However, when dealing with video, especially if the video is compressed (it usually is), figuring out a proper transfer protocol that ensures network robustness is a daunting task to say the least, especially if you're doing this from scratch. Video frames are split up in various packets. Figuring out what to do when these packets are missing is tough.
  2. Synchronization between audio and video. This is a very tough problem and I suggest reading up on protocols such as RTSP (Real-Time Streaming Protocol). This is not an easy task, but here's some introductory info: http://www.cs.columbia.edu/~hgs/rtsp/ - sometimes it's done by sending separate sync packets (some protocols send these over TCP) that tell the player how the sound should match up with the video.
萧瑟寒风 2024-10-06 06:17:52

我会做UDP。然而,这取决于你想要什么。 UDP 将丢弃数据包而不是等待 (TCP)。权衡在于您是否想要一种稳定但有时缓慢且成本高昂的产品,或者一种高效但有时可能无法交付的产品。当涉及到如何实现它以及如何使用它时,选择权在您手中。

I would do UDP. However it depends on what you want. UDP will drop packets rather than wait (TCP). The trade off is whether you want a stable, but sometimes slow and costly, or one that is efficient, but sometimes may not get delivered. The choice is yours when it comes to how you want to implement it and how you are using it.

怀里藏娇 2024-10-06 06:17:52

如今,甚至 YouTube 也通过 HTTP 进行流传输...这是一个 Nodejs 应用程序,它将文件流式传输到浏览器客户端...用作实时流视频与音频完美同步的起点

// usage 
// do following on server side (your laptop running nodejs)
// node this_file.js
//
// then once above is running point your browser at
//    http://localhost:8888
//
// of course your browser could be on your mobile or own custom app



var http = require('http'),
    fs = require('fs'),
    util = require('util');

var path = "/path/to/audio/or/video/file/local/to/server/cool.mp4"; // put any audio or video file here

var port = 8888;
var host = "localhost";

http.createServer(function (req, res) {

  var stat = fs.statSync(path);
  var total = stat.size;

  if (req.headers.range) {   // meaning client (browser) has moved the forward/back slider
                                         // which has sent this request back to this server logic ... cool
    var range = req.headers.range;
    var parts = range.replace(/bytes=/, "").split("-");
    var partialstart = parts[0];
    var partialend = parts[1];

    var start = parseInt(partialstart, 10);
    var end = partialend ? parseInt(partialend, 10) : total-1;
    var chunksize = (end-start)+1;
    console.log('RANGE: ' + start + ' - ' + end + ' = ' + chunksize);

    var file = fs.createReadStream(path, {start: start, end: end});
    res.writeHead(206, { 'Content-Range': 'bytes ' + start + '-' + end + '/' + total, 'Accept-Ranges': 'bytes', 'Content-Length': chunksize, 'Content-Type': 'video/mp4' });
    file.pipe(res);

  } else {

    console.log('ALL: ' + total);
    res.writeHead(200, { 'Content-Length': total, 'Content-Type': 'video/mp4' });
    fs.createReadStream(path).pipe(res);
  }
}).listen(port, host);

console.log("Server running at http://" + host + ":" + port + "/");

Today even youtube streams over HTTP ... here is a nodejs app which streams a file to the browser client ... use as a starting point to live stream video with audio nicely in sync

// usage 
// do following on server side (your laptop running nodejs)
// node this_file.js
//
// then once above is running point your browser at
//    http://localhost:8888
//
// of course your browser could be on your mobile or own custom app



var http = require('http'),
    fs = require('fs'),
    util = require('util');

var path = "/path/to/audio/or/video/file/local/to/server/cool.mp4"; // put any audio or video file here

var port = 8888;
var host = "localhost";

http.createServer(function (req, res) {

  var stat = fs.statSync(path);
  var total = stat.size;

  if (req.headers.range) {   // meaning client (browser) has moved the forward/back slider
                                         // which has sent this request back to this server logic ... cool
    var range = req.headers.range;
    var parts = range.replace(/bytes=/, "").split("-");
    var partialstart = parts[0];
    var partialend = parts[1];

    var start = parseInt(partialstart, 10);
    var end = partialend ? parseInt(partialend, 10) : total-1;
    var chunksize = (end-start)+1;
    console.log('RANGE: ' + start + ' - ' + end + ' = ' + chunksize);

    var file = fs.createReadStream(path, {start: start, end: end});
    res.writeHead(206, { 'Content-Range': 'bytes ' + start + '-' + end + '/' + total, 'Accept-Ranges': 'bytes', 'Content-Length': chunksize, 'Content-Type': 'video/mp4' });
    file.pipe(res);

  } else {

    console.log('ALL: ' + total);
    res.writeHead(200, { 'Content-Length': total, 'Content-Type': 'video/mp4' });
    fs.createReadStream(path).pipe(res);
  }
}).listen(port, host);

console.log("Server running at http://" + host + ":" + port + "/");
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文