WPEWebkit调试MSE播放

下载mse-demo

git clone https://github.com/bitmovin/mse-demo

cog启动

cog运行,每次都要配置编译时用的环境变量

export PATH=$PATH:/home/hui/disk4t/codes/wpe/source/inst/bin

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/hui/disk4t/codes/wpe/source/inst/lib:/home/hui/disk4t/codes/wpe/source/inst/lib/x86_64-linux-gnu

export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/home/hui/disk4t/codes/wpe/source/inst/lib/pkgconfig:/home/hui/disk4t/codes/wpe/source/inst/lib/x86_64-linux-gnu/pkgconfig
cog --platform=x11 file:///home/hui/webkit-debug/mse-demo/index.html

Tools/TestWebKitAPI/Tests/WebKit/file-with-mse.html文件中,也是mse的测试代码,可以参考修改下上面的这个html,增加一个button以方便attach到WPEWebprocess进程进行调试。

diff --git a/index.html b/index.html
index 58aa0e5..b22f048 100644
--- a/index.html
+++ b/index.html
@@ -6,12 +6,12 @@
 </head>
 <body>
   <h1>MSE Demo</h1>
-  <div>
-    <video controls width="80%"></video>
-  </div>
-
+   <div>
+   <video id="player" controls width="80%" ></video>
+   </div>
+  <button οnclick="playVideo()">play video</button>
   <script type="text/javascript">
-    (function() {
+    function playVideo() {
       var baseUrl = 'https://bitdash-a.akamaihd.net/content/MI201109210084_1/video/720_2400000/dash/';
       var initUrl = baseUrl + 'init.mp4';
       var templateUrl = baseUrl + 'segment_$Number$.m4s';
@@ -68,7 +68,7 @@
 
         xhr.send();
       }
-    })();
+    };
   </script>
 </body>
-</html>
+</html>
  <script>
    var v = document.getElementById("player");
    v.onclick = function() {
        if (v.playing) {
          v.play();
        } else {
          v.pause();
        }
    };
  </script>
  

通过增加js代码,直接利用video标签的play按钮的代码不起作用,还需要研究下。

获取journal输出

journalctl -ef | grep -E "WPEWebProcess|WPENetworkProcess"

security origin

运行cog时,发现cog起来后页面加载不出来,chrome播放正常,log中有:

was rejected by SecurityOrigin

是被SecurityOrigin这个地方直接return了,为了测试,直接修改这个地方,返回true,编译运行就可以了。

    RefPtr<Frame> frame = document().frame();
    if (!frame || !document().securityOrigin().canDisplay(url)) {
        if (actionIfInvalid == Complain) {
            FrameLoader::reportLocalLoadFailed(frame.get(), url.stringCenterEllipsizedToLength());
            ERROR_LOG(LOGIDENTIFIER, url , " was rejected by SecurityOrigin");
        }
-       return false;
+       return true;
    }

在做完这些之后,通过qtcreator断点调试就可以了,可以方便的看到mediasource和sourcebuffer的调用栈。

mediasource的创建

MediaSource是在js中通过代码调用才能创建,并不是所有的html5 video都是MSE,所以刚开始接触的时候,用https://www.w3.org/2010/05/video/mediaevents.html的测试页面,就没有这个过程,很怀疑是不是代码思路看错了。

1  WebCore::MediaSource::MediaSource
2  WebCore::MediaSource::create
3  WebCore::JSDOMConstructor<WebCore::JSMediaSource>::construct

addSourceBuffer

同样,sourcebuffer的创建也是通过js代码的调用才走到底层C++代码的,addSourceBuffer

1  WebCore::SourceBufferPrivateGStreamer::SourceBufferPrivateGStreamer
2  WebCore::SourceBufferPrivateGStreamer::create
3  WebCore::MediaSourcePrivateGStreamer::addSourceBuffer
4  WebCore::MediaSource::createSourceBufferPrivate
5  WebCore::MediaSource::addSourceBuffer
6  WebCore::jsMediaSourcePrototypeFunction_addSourceBufferBody
8  WebCore::jsMediaSourcePrototypeFunction_addSourceBuffer

通过断点设置,可以快速的看到AppendPipeline的创建所做的工作:

1   WebCore::HTMLMediaElement::prepareToPlay  
2   WebCore::HTMLMediaElement::updatePlayState
3   WebCore::HTMLMediaElement::setReadyState    
4   WebCore::HTMLMediaElement::mediaPlayerReadyStateChanged
5   WebCore::MediaPlayer::readyStateChanged
6   WebCore::MediaPlayerPrivateGStreamerMSE::setReadyState
7   WebCore::MediaSourcePrivateGStreamer::setReadyState
8   WebCore::SourceBufferPrivateGStreamer::setReadyState
9   WebCore::SourceBuffer::sourceBufferPrivateDidReceiveInitializationSegment
10  WebCore::SourceBufferPrivate::didReceiveInitializationSegment
11  WebCore::SourceBufferPrivateGStreamer::didReceiveInitializationSegment
12  WebCore::AppendPipeline::didReceiveInitializationSegment
14  WTF::Detail::CallableWrapper<WebCore::AppendPipeline::AppendPipeline

AppendPipeline在构造函数里面,no-more-pads信号连接的地方,直接通过lambda表达式调用了didReceiveInitializationSegment:

在这里插入图片描述

html MSE的全部代码

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>MSE Demo</title>
</head>
<body>
  <h1>MSE Demo</h1>
   <div>
      <video id="player" controls width="80%" ></video>
   </div>
  <button onclick="playVideo()" >play video</button>
  
  <script type="text/javascript">  
    function playVideo() {
      var baseUrl = 'https://bitdash-a.akamaihd.net/content/MI201109210084_1/video/720_2400000/dash/';
      var initUrl = baseUrl + 'init.mp4';
      var templateUrl = baseUrl + 'segment_$Number$.m4s';
      var sourceBuffer;
      var index = 0;
      var numberOfChunks = 52;
      var video = document.querySelector('video');

      if (!window.MediaSource) {
        console.error('No Media Source API available');
        return;
      }

      var ms = new MediaSource();
      video.src = window.URL.createObjectURL(ms);
      ms.addEventListener('sourceopen', onMediaSourceOpen);

      function onMediaSourceOpen() {
        sourceBuffer = ms.addSourceBuffer('video/mp4; codecs="avc1.4d401f"');
        sourceBuffer.addEventListener('updateend', nextSegment);

        GET(initUrl, appendToBuffer);

        video.play();
      }

      function nextSegment() {
        var url = templateUrl.replace('$Number$', index);
        GET(url, appendToBuffer);
        index++;
        if (index > numberOfChunks) {
          sourceBuffer.removeEventListener('updateend', nextSegment);
        }
      }

      function appendToBuffer(videoChunk) {
        if (videoChunk) {
          sourceBuffer.appendBuffer(new Uint8Array(videoChunk));
        }
      }

      function GET(url, callback) {
        var xhr = new XMLHttpRequest();
        xhr.open('GET', url);
        xhr.responseType = 'arraybuffer';

        xhr.onload = function(e) {
          if (xhr.status != 200) {
            console.warn('Unexpected status code ' + xhr.status + ' for ' + url);
            return false;
          }
          callback(xhr.response);
        };

        xhr.send();
      }
    };
  </script>
</body>
</html>



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值