2015-05-22 20 views
16

Tôi đang sử dụng WebRTC để gửi video từ máy chủ đến trình duyệt của khách hàng (sử dụng số WebRTC API và máy chủ MCU WebRTC như Kurento).Đồng bộ hóa dữ liệu với video bằng WebRTC

Trước khi gửi cho khách hàng mỗi khung video chứa siêu dữ liệu (như phụ đề hoặc bất kỳ nội dung đăng ký nào khác). Tôi đang tìm một cách để gửi siêu dữ liệu này cho khách hàng sao cho nó vẫn được đồng bộ hóa (đến thời điểm nó thực sự là được trình bày). Ngoài ra, tôi muốn có thể truy cập dữ liệu này từ phía máy khách (bằng Javascript).

Một số tùy chọn Tôi nghĩ về:

  • gửi các dữ liệu do WebRTC DataChannel. Nhưng tôi không biết làm thế nào để đảm bảo dữ liệu được đồng bộ hóa trên cơ sở mỗi khung hình. Nhưng tôi không thể tìm thấy một cách để đảm bảo dữ liệu được gửi bởi kênh dữ liệu và kênh video được đồng bộ hóa (một lần nữa, tôi hy vọng sẽ nhận được mức độ chính xác của một khung hình duy nhất).
  • Gửi dữ liệu theo cách thủ công cho khách hàng theo cách nào đó (WebRTC DataChannel, websockets, v.v.) với dấu thời gian phù hợp với dấu thời gian của video. Tuy nhiên, ngay cả khi Kurento hoặc các máy chủ trung gian khác giữ lại thông tin dấu thời gian trong video, theo câu trả lời sau đây, không có cách áp dụng để nhận được dấu thời gian video từ javascript: How can use the webRTC Javascript API to access the outgoing audio RTP timestamp at the sender and the incoming audio RTP timestamp at the receiver?. Tôi đã nghĩ đến việc sử dụng sự kiện timeupdate của phần tử video chuẩn, nhưng tôi không konw nếu nó sẽ hoạt động với mức độ chính xác của khung hình và tôi không chắc nó có nghĩa gì trong video trực tiếp như trong WebRTC.
  • Gửi dữ liệu theo cách thủ công và đính kèm dữ liệu vào video theo cách khác như TextTrack. Sau đó, sử dụng onenteronexit để đọc đồng bộ: http://www.html5rocks.com/en/tutorials/track/basics/. Nó vẫn đòi hỏi các dấu thời gian chính xác, và tôi không chắc chắn làm thế nào để biết các dấu thời gian là gì và nếu Kurento vượt qua chúng.
  • Sử dụng API thống kê của WebRTC để đếm số khung theo cách thủ công (sử dụng getstats) và hy vọng rằng thông tin được cung cấp bởi API này là chính xác.

Cách tốt nhất để làm điều đó là gì và cách giải quyết các vấn đề tôi đã đề cập theo cách nào?

CHỈNH SỬA: Đồng bộ hóa chính xác (ở độ phân giải không quá một khung) siêu dữ liệu với khung thích hợp là bắt buộc.

+0

Bạn sẽ không bao giờ nhận được luồng đồng bộ hoàn hảo nếu bạn tách chúng ra. Bạn có thể thực hiện một hệ thống đệm để đảm bảo không có tiến bộ về phía trước cho đến khi có bộ đệm chấp nhận được có sẵn trong cả hai luồng. Đặt cược tốt nhất của bạn là quên khung hoàn hảo để khớp khung hình, nếu bạn muốn sau đó mã hóa nó thành luồng video dưới dạng video khi đang di chuyển. Ngoài âm thanh và đồ họa, tôi không thể nghĩ tại sao bạn lại cần độ chính xác cao như vậy. Một trong những bạn quên những điều thời gian hoàn hảo sẽ đơn giản hơn rất nhiều. – Blindman67

+0

Cảm ơn, điểm tốt. Dù sao thì câu hỏi là về cách làm điều đó theo lập trình, giả sử rằng tôi có thể đảm bảo rằng luồng siêu dữ liệu đã được tiếp cận với trình duyệt trước luồng video. Đề xuất của bạn để mã hóa lại video có vẻ tốt đẹp, nhưng tôi vẫn cần phải khớp với thời gian của luồng video và luồng siêu dữ liệu - Tôi thậm chí không chắc chắn rằng máy chủ trung lưu giữ dấu thời gian trình bày. – MaMazav

+1

Luồng truyền thông cung cấp một số trợ giúp. Nếu bạn đang sử dụng video HTML5, bạn có thể sử dụng bộ đệm để trả về một đối tượng TimeRanges để cho bạn biết những gì đã được đệm. Giao diện HTMLMediaElement cung cấp currentTime như một thuộc tính ghi đọc. Bạn có thể sử dụng nó để có thời gian tính bằng giây của video. Để có được số khung hiện tại 'frameNumber = Math.floor (videoElement.currentTime/frameRate);' Viết tới currentTime sẽ khiến video tìm kiếm thời gian đó. – Blindman67

Trả lời

1

Tôi nghi ngờ lượng dữ liệu trên mỗi khung hình là khá nhỏ. Tôi sẽ xem xét mã hóa nó thành một hình ảnh mã vạch 2D và đặt nó trong mỗi khung hình theo một cách để nó không được loại bỏ bằng cách nén. Ngoài ra, chỉ cần mã hóa dấu thời gian như thế này.

Sau đó, ở phía trình phát, bạn nhìn vào hình ảnh trong một khung hình cụ thể và lấy dữ liệu ra hoặc nếu có.

2

Ok, đầu tiên cho phép có được những video và âm thanh sử dụng getUserMedia và cho phép làm cho nó dữ liệu thô sử dụng

https://github.com/streamproc/MediaStreamRecorder

:

/* 
* 
* Video Streamer 
* 
*/ 


<script src="https://cdn.webrtc-experiment.com/MediaStreamRecorder.js"> </script> 
<script> 

// FIREFOX 

var mediaConstraints = { 
    audio: !!navigator.mozGetUserMedia, // don't forget audio! 
    video: true       // don't forget video! 
}; 

navigator.getUserMedia(mediaConstraints, onMediaSuccess, onMediaError); 

function onMediaSuccess(stream) { 
    var mediaRecorder = new MediaStreamRecorder(stream); 
    mediaRecorder.mimeType = 'video/webm'; 
    mediaRecorder.ondataavailable = function (blob) { 
     // POST/PUT "Blob" using FormData/XHR2 

    }; 
    mediaRecorder.start(3000); 
} 

function onMediaError(e) { 
    console.error('media error', e); 
} 
</script> 



// CHROME 

var mediaConstraints = { 
    audio: true, 
    video: true 
}; 

navigator.getUserMedia(mediaConstraints, onMediaSuccess, onMediaError); 

function onMediaSuccess(stream) { 
    var multiStreamRecorder = new MultiStreamRecorder(stream); 
    multiStreamRecorder.video = yourVideoElement; // to get maximum accuracy 
    multiStreamRecorder.audioChannels = 1; 
    multiStreamRecorder.ondataavailable = function (blobs) { 
     // blobs.audio 
     // blobs.video 
    }; 
    multiStreamRecorder.start(3000); 
} 

function onMediaError(e) { 
    console.error('media error', e); 
} 

Bây giờ bạn có thể gửi dữ liệu thông qua DataChannels và thêm metadata của bạn, ở phía người nhận:

/* 
* 
* Video Receiver 
* 
*/ 


var ms = new MediaSource(); 

var video = document.querySelector('video'); 
video.src = window.URL.createObjectURL(ms); 

ms.addEventListener('sourceopen', function(e) { 
    var sourceBuffer = ms.addSourceBuffer('video/webm; codecs="vorbis,vp8"'); 
    sourceBuffer.appendBuffer(/* Video chunks here */); 
}, false); 
+0

Có vẻ như một hướng tốt đẹp. Tuy nhiên tôi chưa hiểu làm thế nào tôi có thể SYNCHRONIZE siêu dữ liệu vào đúng khung hình video? Và dù sao tôi không thích sử dụng MediaSource vì nó có một số hạn chế (ví dụ: phân đoạn nên bắt đầu bằng keyframe https://code.google.com/p/chromium/issues/detail?id=229412) – MaMazav

+1

Vâng, bạn có dữ liệu vídeo , vì vậy bây giờ bạn có thể thao tác nó trong lần thử đầu tiên có thể với bộ hẹn giờ và đặt độ trễ nhiều hơn hoặc ít hơn khi cần, đó là cách duy nhất tôi nghĩ chúng tôi có ngay bây giờ hoặc không sử dụng webRTC, truy cập websockets. – Jairo

+0

Bộ hẹn giờ không đủ chính xác cho nhu cầu của tôi. Websockets là một ý tưởng tuyệt vời mà tôi đã nghiên cứu, tuy nhiên sau đó tôi cần phải sử dụng MediaSource có nhược điểm của nó. – MaMazav

Các vấn đề liên quan