2017-11-13 5 views
0

에 표시하지만, 파이어 폭스에서 잘 작동하지 않습니다.조각난 MP4 크롬

구글 크롬 버전 : 61.0.3163.100 (공식 빌드) (64 비트)

모질라 파이어 폭스 버전 : 56.0.2 (64 비트)

조각난 MP4가 이상 스트림 내 비디오 웹 소켓 A와 client html 페이지에서 MSE로 가져옵니다. 비디오 코덱은 H264 Main Profile입니다. 비디오 정보는 FFPROBE 및 다른 검사관에서 검사하여 데이터 무결성을 확인합니다. FMP4를 멀티플렉싱 할 때 다음과 같은 플래그가 사용된다 : 나는 또한 이중 첫 번째 조각은 24 바이트 크기의 소위 "초기화 부분"이라고 확인

"empty_moov+default_base_moof+frag_keyframe" 

. 내가 말했듯이, 파이어 폭스 재생 괜찮습니다.

<!DOCTYPE html> 
<html lang="en"> 
<head> 
    <meta charset="UTF-8"> 
    <title>MSE Demo</title> 
</head> 

<body> 
    <h1>MSE Demo</h1> 
    <div> 
     <video id="video1" controls width="80%" autoplay="true"> </video> 
    </div> 
<script type="text/javascript"> 
    (function() { 

     var mime = 'video/mp4; codecs="avc1.4D401E"'; 

     if (!MediaSource.isTypeSupported(mime)) { 
      document.querySelector('h1').append(' - Unsuported mime type :('); 
      return; 
     } 

     var buffer; 
     var websocket; 
     var buffer_size = 4 * 1024 * 1024; 
     var buffer_index = 0; 
     var frag_mp4_buffer = new Uint8Array(buffer_size); 
     var video = document.querySelector('video'); 
     var mediaSource = new MediaSource(); 

     mediaSource.addEventListener('sourceended', function (e) { console.log('sourceended: ' + mediaSource.readyState); }); 
     mediaSource.addEventListener('sourceclose', function (e) { console.log('sourceclose: ' + mediaSource.readyState); }); 
     mediaSource.addEventListener('error', function (e) { console.log('error: ' + mediaSource.readyState); }); 

     video.src = window.URL.createObjectURL(mediaSource); 
     video.crossOrigin = 'anonymous'; 

     mediaSource.addEventListener('sourceopen', function (e) { 
      console.log('sourceopen: ' + mediaSource.readyState); 
      //doesn't help: 
      // var playPromise = video.play(); 
      // In browsers that don’t yet support this functionality, 
      // playPromise won’t be defined. 
      /* 
      if (playPromise !== undefined) { 
       playPromise.then(function() { 
        // Automatic playback started! 
       }).catch(function (error) { 
        // Automatic playback failed. 
        // Show a UI element to let the user manually start playback. 
       }); 
      } 
      */ 

      buffer = mediaSource.addSourceBuffer(mime); 

      buffer.addEventListener('updateend', function (e) { 
       if (video.duration && !video.currentTime) { 
        video.currentTime = video.duration; 
       } 
      }); 

      var websocket = new WebSocket('ws://' + document.location.hostname + ':8080'); 
      websocket.binaryType = 'arraybuffer'; 

      websocket.addEventListener('message', function (e) { 
       var data = new Uint8Array(e.data); 
       console.log("got packet! size:" + data.length); 
       if (data.length) { 
        if ((buffer_index + data.length) <= buffer_size) { 
         frag_mp4_buffer.set(data, buffer_index); 
         buffer_index = buffer_index + data.length; 

         if (!buffer.updating && mediaSource.readyState == 'open') 
         { 
          var appended = frag_mp4_buffer.slice(0, buffer_index); 
          buffer.appendBuffer(appended); 
          frag_mp4_buffer.fill(0); 
          buffer_index = 0; 

         } 
        } 
       } 
      }, false); 
     }, false); 
    })(); 
    </script> 
</body> 

또 다른 중요한 정보를, 당신은 내가 video.play() 전화에서 주석 볼 수 있습니다 여기에

는 클라이언트 (대부분 here에서 차용) 코드입니다. (약속을)

catch되지 않은 예외 : DOMException : 더 지원 소스가

발견했기 때문에 나는 here에서 다음과 같은 솔루션을 시도로드하지 못했습니다 즉 실제로 응용 프로그램 시작 오류가 발생 유일한 장소 :

 var playPromise = video.play(); 

     if (playPromise !== undefined) { 
       playPromise.then(function() { 
        // Automatic playback started! 
       }).catch(function (error) { 
        // Automatic playback failed. 
        $(document).on('click', '#video1', function (e) { 
         var video = $(this).get(0); 
         if (video.paused === false) { 
          video.pause(); 
         } else { 
          video.play(); 
         } 

         return false; 
        }); 
       }); 
     } 

하지만 아무 것도 변경되지 않았습니다. 비디오 영역은 항상 흰색입니다.

답변

0

난 그냥이 mse example를 사용하여, 나는 단지 내 조각 MP4 파이어 폭스에서 플레이를 할 수있는 유사한 문제로 실행,하지만 크롬에. 내 조각난 mp4가 제대로 포맷되었는지 확인하기 위해 websocket을 통해 파일을 보내는 대신 전체 파일을 먼저 전달하려고했습니다. 내가 찾은 문제는 내는 FFmpeg 명령에 경우는 그때 내 파일이 크롬에서 재생되지 것 오디오를 제거하는 inlcuded입니다 것을 만, 여전히 파이어 폭스에서 일했다. 오디오 플래그를 사용하지 않거나 특별히 -c:a libfdk_aac을 사용하면 내 mp4를 Chrome 및 Firefox에서 재생할 수있었습니다. 또한 모든 다른 movflags 대신 -movflags +dash 만 있으면됩니다. 내 코드에 참고로 나는 따라서 -c:v copy, H264 비디오로 인코딩 된 IP 카메라에서 RTSP 피드를 사용하고, 아래의 스 니펫.Mac에서 테스트

는 파이어 폭스와 사파리가 아니라 크롬에 근무 :

ffmpeg -i input_source -an -c:v copy -f mp4 -movflags +dash dash.mp4

맥에서 테스트, 파이어 폭스와 사파리와 크롬에 근무

ffmpeg -i input_source -c:v copy -f mp4 -movflags +dash dash.mp4

ffmpeg -i input_source -c:a libfdk_aac -c:v copy -f mp4 -movflags +dash dash.mp4

*이 편집 난 그냥 오디오의 인코딩이 크롬에 재생과 관련된 이유의 자세한 정보를 발견했다. 파이어 폭스와 사파리처럼 mimetype/codec이 잘못되어 크롬이 용서를받지 못했습니다. var mimeCodec = 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"'; var mimeCodec = 'video/mp4; codecs="avc1.42E01E"';으로 변경했으며 오디오가 인코딩되지 않은 이 (가) 다른 브라우저에서도 재생되는 mp30로 변경되었습니다. 아마도 오디오는 가지고 있지만 코덱의 오디오 부분은 포함하지 않았을 것입니까? 또는 귀하의 비디오 코덱이 귀하의 비디오에 적합한 비디오 코덱이 아닙니까? 파일을 만드는 데 사용 된 전체 ffmpeg 명령을 보지 않고도 말하기가 어렵습니다.

* 두 번째 편집. ffmpeg, nodejs, express 및 socket.io를 사용하여 미디어 소스 확장에서 라이브 스트리밍 mp4를 테스트하기 위해 little project을 만들었습니다. 가장자리가 약간 거칠지 만 대부분 효과가 있습니다.