2013-12-18 2 views
5

previous question에서 설명한 것처럼 라이브 스트리밍하는 낮은 품질의 오디오을 mp3로 변환 한 후 프로토 타입 (MVC Web API, NAudio 및 NAudio.Lame 사용)을 만들었습니다. 원본 스트림은 PCM : 8K, 16 비트, 모노이며 html5의 오디오 태그를 사용하고 있습니다. 오디오가 내가 말한있어, 브라우저에서 들리는 전에HTML5 <audio> 라이브 스트리밍에 대한 좋지 않은 선택입니까?

에 모두 크롬과 IE11은 15-34초 지연 (대기 시간)이 우리의 최종 사용자가 될 수 없습니다. 이상적으로 대기 시간은 5 초 이상이되지 않습니다. 내 오디오 태그에서 preload = "none"속성을 사용하는 경우에도 지연이 발생합니다.

문제를 자세히 살펴보면 ~ 32K의 오디오 데이터를 수신 할 때까지 두 브라우저 모두 에서 오디오 재생이 시작되지 않는 것처럼 보입니다. 이를 염두에두고 Lame의 MP3 비트 레이트 설정을 변경하여 지연에 영향을 줄 수 있습니다. 그러나 지연을 줄이면 (같은 길이의 오디오에 대해 브라우저에 더 많은 데이터를 보내서) 오디오 드롭 아웃을 나중에 소개합니다.

예 : 내가 불쌍해의 V0 인코딩을 사용하는 경우

  • 지연이 소스 오디오의 약 0.5 MB를 필요로 거의 34초입니다.
  • Lame의 ABR_32 인코딩을 사용하면 지연을 10-15 초로 줄일 수 있지만 청취 세션 전체에서 일시 중지 및 중단이 발생합니다.

질문 :

  1. 나는 가동 지연 (대기 시간)을 최소화 할 수있는 모든 아이디어를 어떻게가?
  2. "올바른"것을 선택하기 위해 여러가지 절름발이 '프리셋'을 계속 조사해야합니까?
  3. MP3가 이 아닐 수도 있습니다 스트리밍에 가장 적합한 형식은입니다.
  4. Ogg/Vorbis (또는 Ogg/OPUS)로 전환하면 도움이 될까요?
  5. 우리는 을 포기해야합니다. HTML5의 오디오 태그는 플래시 또는 자바 애플릿을 사용합니까?

감사합니다.

답변

4

브라우저 코드 및 버퍼링 크기를 제어 할 수 없기 때문에 지연을 줄일 수 없습니다. HTML5 사양은 제약 조건을 적용하지 않으므로 개선 될만한 이유는 없습니다.

하지만 스트리밍을 직접 처리하는 webaudio API (매우 간단 함)를 사용하여 솔루션을 구현할 수 있습니다.

MP3 덩어리를 고정 크기로 분할하여 (미리 MP3 덩어리 크기를 미리 알 수 있도록 또는 적어도 수신 할 때) 20 줄의 코드로 실시간 스트리밍 할 수 있습니다. 청크 크기가 대기 시간입니다.

키는 AudioContext :: decodeAudioData를 사용하는 것입니다.

// Fix up prefixing 
window.AudioContext = window.AudioContext || window.webkitAudioContext; 
var context = new AudioContext(); 
var offset = 0; 
var byteOffset = 0; 
var minDecodeSize = 16384; // This is your chunk size 

var request = new XMLHttpRequest(); 
request.onprogress = function(evt) 
{ 
    if (request.response) 
    { 
     var size = request.response.length - byteOffset; 
     if (size < minDecodeSize) return; 
     // In Chrome, XHR stream mode gives text, not ArrayBuffer. 
     // If in Firefox, you can get an ArrayBuffer as is 
     var buf; 
     if (request.response instanceof ArrayBuffer) 
      buf = request.response; 
     else 
     { 
      ab = new ArrayBuffer(size); 
      buf = new Uint8Array(ab); 
      for (var i = 0; i < size; i++) 
       buf[i] = request.response.charCodeAt(i + byteOffset) & 0xff; 
     } 
     byteOffset = request.response.length; 
     context.decodeAudioData(ab, function(buffer) { 
      playSound(buffer); 
     }, onError); 
    } 
}; 
request.open('GET', url, true); 
request.responseType = expectedType; // 'stream' in chrome, 'moz-chunked-arraybuffer' in firefox, 'ms-stream' in IE 
request.overrideMimeType('text/plain; charset=x-user-defined'); 
request.send(null); 

function playSound(buffer) { 
    var source = context.createBufferSource(); // creates a sound source 
    source.buffer = buffer;     // tell the source which sound to play 
    source.connect(context.destination);  // connect the source to the context's destination (the speakers) 
    source.start(offset);       // play the source now 
              // note: on older systems, may have to use deprecated noteOn(time); 
    offset += buffer.duration; 
}