通過 WebRTC 共享屏幕很容易

簡介

網(wǎng)絡(luò)會(huì)議中常用的屏幕共享功能使用
WebRTC 提供的 getDisplayMedia API 就能輕松實(shí)現(xiàn)窒朋,接口如下

var promise = navigator.mediaDevices.getDisplayMedia(constraints);

MediaDevices 接口的 getDisplayMedia 方法提示用戶選擇并授予將顯示屏幕或其部分(如瀏覽器窗口和標(biāo)簽頁)的內(nèi)容捕獲為 MediaStream 的權(quán)限最蕾。然后,可以使用媒體流錄制 API 錄制, 或作為 WebRTC 會(huì)話的一部分傳輸所生成的媒體流杠纵。這個(gè)媒體流傳輸?shù)骄W(wǎng)絡(luò)的對端,這樣就可以共享屏幕的內(nèi)容了慈参。

例如

async function startCapture(displayMediaOptions) {
  let captureStream = null;

  try {
    captureStream = await navigator.mediaDevices.getDisplayMedia(displayMediaOptions);
  } catch(err) {
    console.error("Error: " + err);
  }
  return captureStream;
}

示例1

  • HTML 文件
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<!-- 省略引入的 JS 和 CSS -->
<body>

<!-- <a ><img style="position: absolute; top: 0; left: 0; border: 0; z-index: 1001;" src="https://s3.amazonaws.com/github/ribbons/forkme_left_darkblue_121621.png" alt="Fork me on GitHub"></a>
 -->
<nav class="navbar navbar-default navbar-static-top">
</nav>

<div class="container">
    <div class="row">
        <div class="col-lg-12">
            <div class="page-header">
                <h1>WebRTC example of Desktop Sharing </h1>
            </div>
            <div class="container" id="details">
          <div class="row">

              <div class="col-lg-12">

                <p>Click the button to open or close connection</p>
                <div>

                    <button class="btn btn-default" autocomplete="off" id="startButton">Share Something</button>
                </div>
                <br/>
              </div>
              <div class="col-lg-12">
                    <div class="col-lg-6">
                        <video id="localVideo" autoplay playsinline muted></video>
                    </div>
               </div>
          </div>
    <hr>
    <div class="footer">
    </div>
</div>
<script type="text/javascript" src="js/desktop_sharing_demo.js"></script>
</body>
</html>

  • JS 文件
'use strict';

// Polyfill in Firefox.
// See https://blog.mozilla.org/webrtc/getdisplaymedia-now-available-in-adapter-js/
if (adapter.browserDetails.browser == 'firefox') {
  adapter.browserShim.shimGetDisplayMedia(window, 'screen');
}

const gdmOptions = {
  video: {
    cursor: "always"
  },
  audio: {
    echoCancellation: true,
    noiseSuppression: true,
    sampleRate: 44100
  }
}

function handleSuccess(stream) {
  startButton.disabled = true;
  const video = document.querySelector('video');
  video.srcObject = stream;

  // demonstrates how to detect that the user has stopped
  // sharing the screen via the browser UI.
  stream.getVideoTracks()[0].addEventListener('ended', () => {
    errorMsg('The user has ended sharing the screen');
    startButton.disabled = false;
  });
}

function handleError(error) {
  errorMsg(`getDisplayMedia error: ${error.name}`, error);
}

function errorMsg(msg, error) {
  const errorElement = document.querySelector('#errorMsg');
  errorElement.innerHTML += `<p>${msg}</p>`;
  if (typeof error !== 'undefined') {
    console.error(error);
  }
}

const startButton = document.getElementById('startButton');
startButton.addEventListener('click', () => {
  navigator.mediaDevices.getDisplayMedia(gdmOptions)
      .then(handleSuccess, handleError);
});

if ((navigator.mediaDevices && 'getDisplayMedia' in navigator.mediaDevices)) {
  startButton.disabled = false;
} else {
  errorMsg('getDisplayMedia is not supported');
}

測試

點(diǎn)擊 share 按鍵推沸,可以選擇 為文本 還是 運(yùn)動(dòng)共享,后者的幀率會(huì)高點(diǎn)议泵。然后再選擇屏幕占贫,應(yīng)用或標(biāo)簽頁。

示例2

服務(wù)器端

使用 nodejs + socket.io 充當(dāng)web服務(wù)器先口,并用來傳遞 sdp

代碼:https://github.com/walterfan/webrtc_remote_sharing

啟動(dòng)命令

node screen_share_server.js
[2021-04-21T20:18:41.018] [INFO] screen_share - screen shares server listen on https://localhost:8183

客戶端還是 html + JavaScript

詳細(xì)代碼:

測試

將 getDisplayMedia 得到的媒體流 MediaStream 通過 PeerConnection 傳送給對方

  1. 張三進(jìn)入會(huì)議室 "Join room"
  2. 李四進(jìn)入會(huì)議室 "Join room"
  3. 張三分享屏幕 "start share"
本地屏幕
  1. 李四就會(huì)看到分享的屏幕內(nèi)容
遠(yuǎn)端屏幕

注意我們需要觀察 RTP 包的荷載內(nèi)容型奥,所以要關(guān)掉 SRTP 瞳收,只用 RTP 來傳輸
出于測試目的, Chrome Canary 及 Chrome Developer 有一個(gè)選項(xiàng) --disable-webrtc-encryption 可以關(guān)掉 SRTP

在我的 macbook 上步驟如下:

cd /Applications/Google\ Chrome\ Canary.app/Contents/MacOS/
./Google\ Chrome\ Canary --disable-webrtc-encryption

于是在創(chuàng)建 RTP 連接時(shí)的 SDP 就從:

m=video 9 RTP/SAVPF 96 97 98 99 100 101 102 121 127 120 125 107 108 109 35 36 124 119 123 118 114 115 116

就變成了

m=video 9 RTP/AVPF 96 97 98 99 100 101 102 121 127 120 125 107 108 109 35 36 124 119 123 118 114 115 116

完整sdp如下

  • offer sdp 消息:
{
  type: 'offer',
  sdp: 'v=0\r\n' +
    'o=- 2151254633287699884 2 IN IP4 127.0.0.1\r\n' +
    's=-\r\n' +
    't=0 0\r\n' +
    'a=group:BUNDLE 0 1\r\n' +
    'a=extmap-allow-mixed\r\n' +
    'a=msid-semantic: WMS VLvw0Ec4NwiXKVzTZyzl1m5aSLGW9EPe50Mz\r\n' +
    'm=audio 9 UDP/TLS/RTP/SAVPF 111 103 104 9 0 8 106 105 13 110 112 113 126\r\n' +
    'c=IN IP4 0.0.0.0\r\n' +
    'a=rtcp:9 IN IP4 0.0.0.0\r\n' +
    'a=ice-ufrag:wkaf\r\n' +
    'a=ice-pwd:2PI01Rh/wf4JKpfM0pr6LJ+d\r\n' +
    'a=ice-options:trickle\r\n' +
    'a=fingerprint:sha-256 86:BC:0B:F2:AB:2F:A2:A0:7F:FC:5B:5E:16:B8:61:62:E6:E6:18:FF:B6:85:6C:F0:DD:65:01:72:C1:16:88:E8\r\n' +
    'a=setup:actpass\r\n' +
    'a=mid:0\r\n' +
    'a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level\r\n' +
    'a=extmap:2 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time\r\n' +
    'a=extmap:3 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01\r\n' +
    'a=extmap:4 urn:ietf:params:rtp-hdrext:sdes:mid\r\n' +
    'a=extmap:5 urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id\r\n' +
    'a=extmap:6 urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id\r\n' +
    'a=sendrecv\r\n' +
    'a=msid:VLvw0Ec4NwiXKVzTZyzl1m5aSLGW9EPe50Mz cd1c92ae-7d05-4ee8-9e21-3e2993c1c254\r\n' +
    'a=rtcp-mux\r\n' +
    'a=rtpmap:111 opus/48000/2\r\n' +
    'a=rtcp-fb:111 transport-cc\r\n' +
    'a=fmtp:111 minptime=10;useinbandfec=1\r\n' +
    'a=rtpmap:103 ISAC/16000\r\n' +
    'a=rtpmap:104 ISAC/32000\r\n' +
    'a=rtpmap:9 G722/8000\r\n' +
    'a=rtpmap:0 PCMU/8000\r\n' +
    'a=rtpmap:8 PCMA/8000\r\n' +
    'a=rtpmap:106 CN/32000\r\n' +
    'a=rtpmap:105 CN/16000\r\n' +
    'a=rtpmap:13 CN/8000\r\n' +
    'a=rtpmap:110 telephone-event/48000\r\n' +
    'a=rtpmap:112 telephone-event/32000\r\n' +
    'a=rtpmap:113 telephone-event/16000\r\n' +
    'a=rtpmap:126 telephone-event/8000\r\n' +
    'a=ssrc:3060416220 cname:C9N45apy7vfT4Waq\r\n' +
    'a=ssrc:3060416220 msid:VLvw0Ec4NwiXKVzTZyzl1m5aSLGW9EPe50Mz cd1c92ae-7d05-4ee8-9e21-3e2993c1c254\r\n' +
    'a=ssrc:3060416220 mslabel:VLvw0Ec4NwiXKVzTZyzl1m5aSLGW9EPe50Mz\r\n' +
    'a=ssrc:3060416220 label:cd1c92ae-7d05-4ee8-9e21-3e2993c1c254\r\n' +
    'm=video 9 UDP/TLS/RTP/SAVPF 96 97 98 99 100 101 102 121 127 120 125 107 108 109 124 119 123 118 114 115 116\r\n' +
    'c=IN IP4 0.0.0.0\r\n' +
    'a=rtcp:9 IN IP4 0.0.0.0\r\n' +
    'a=ice-ufrag:wkaf\r\n' +
    'a=ice-pwd:2PI01Rh/wf4JKpfM0pr6LJ+d\r\n' +
    'a=ice-options:trickle\r\n' +
    'a=fingerprint:sha-256 86:BC:0B:F2:AB:2F:A2:A0:7F:FC:5B:5E:16:B8:61:62:E6:E6:18:FF:B6:85:6C:F0:DD:65:01:72:C1:16:88:E8\r\n' +
    'a=setup:actpass\r\n' +
    'a=mid:1\r\n' +
    'a=extmap:14 urn:ietf:params:rtp-hdrext:toffset\r\n' +
    'a=extmap:2 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time\r\n' +
    'a=extmap:13 urn:3gpp:video-orientation\r\n' +
    'a=extmap:3 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01\r\n' +
    'a=extmap:12 http://www.webrtc.org/experiments/rtp-hdrext/playout-delay\r\n' +
    'a=extmap:11 http://www.webrtc.org/experiments/rtp-hdrext/video-content-type\r\n' +
    'a=extmap:7 http://www.webrtc.org/experiments/rtp-hdrext/video-timing\r\n' +
    'a=extmap:8 http://www.webrtc.org/experiments/rtp-hdrext/color-space\r\n' +
    'a=extmap:4 urn:ietf:params:rtp-hdrext:sdes:mid\r\n' +
    'a=extmap:5 urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id\r\n' +
    'a=extmap:6 urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id\r\n' +
    'a=sendrecv\r\n' +
    'a=msid:VLvw0Ec4NwiXKVzTZyzl1m5aSLGW9EPe50Mz 95173d41-de5c-4864-8745-a8573f23f3d8\r\n' +
    'a=rtcp-mux\r\n' +
    'a=rtcp-rsize\r\n' +
    'a=rtpmap:102 H264/90000\r\n' +
    'a=rtcp-fb:102 goog-remb\r\n' +
    'a=rtcp-fb:102 transport-cc\r\n' +
    'a=rtcp-fb:102 ccm fir\r\n' +
    'a=rtcp-fb:102 nack\r\n' +
    'a=rtcp-fb:102 nack pli\r\n' +
    'a=fmtp:102 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42001f\r\n' +
    'a=rtpmap:121 rtx/90000\r\n' +
    'a=fmtp:121 apt=102\r\n' +
    'a=rtpmap:127 H264/90000\r\n' +
    'a=rtcp-fb:127 goog-remb\r\n' +
    'a=rtcp-fb:127 transport-cc\r\n' +
    'a=rtcp-fb:127 ccm fir\r\n' +
    'a=rtcp-fb:127 nack\r\n' +
    'a=rtcp-fb:127 nack pli\r\n' +
    'a=fmtp:127 level-asymmetry-allowed=1;packetization-mode=0;profile-level-id=42001f\r\n' +
    'a=rtpmap:120 rtx/90000\r\n' +
    'a=fmtp:120 apt=127\r\n' +
    'a=rtpmap:125 H264/90000\r\n' +
    'a=rtcp-fb:125 goog-remb\r\n' +
    'a=rtcp-fb:125 transport-cc\r\n' +
    'a=rtcp-fb:125 ccm fir\r\n' +
    'a=rtcp-fb:125 nack\r\n' +
    'a=rtcp-fb:125 nack pli\r\n' +
    'a=fmtp:125 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f\r\n' +
    'a=rtpmap:107 rtx/90000\r\n' +
    'a=fmtp:107 apt=125\r\n' +
    'a=rtpmap:108 H264/90000\r\n' +
    'a=rtcp-fb:108 goog-remb\r\n' +
    'a=rtcp-fb:108 transport-cc\r\n' +
    'a=rtcp-fb:108 ccm fir\r\n' +
    'a=rtcp-fb:108 nack\r\n' +
    'a=rtcp-fb:108 nack pli\r\n' +
    'a=fmtp:108 level-asymmetry-allowed=1;packetization-mode=0;profile-level-id=42e01f\r\n' +
    'a=rtpmap:109 rtx/90000\r\n' +
    'a=fmtp:109 apt=108\r\n' +
    'a=rtpmap:124 H264/90000\r\n' +
    'a=rtcp-fb:124 goog-remb\r\n' +
    'a=rtcp-fb:124 transport-cc\r\n' +
    'a=rtcp-fb:124 ccm fir\r\n' +
    'a=rtcp-fb:124 nack\r\n' +
    'a=rtcp-fb:124 nack pli\r\n' +
    'a=fmtp:124 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=4d0032\r\n' +
    'a=rtpmap:119 rtx/90000\r\n' +
    'a=fmtp:119 apt=124\r\n' +
    'a=rtpmap:123 H264/90000\r\n' +
    'a=rtcp-fb:123 goog-remb\r\n' +
    'a=rtcp-fb:123 transport-cc\r\n' +
    'a=rtcp-fb:123 ccm fir\r\n' +
    'a=rtcp-fb:123 nack\r\n' +
    'a=rtcp-fb:123 nack pli\r\n' +
    'a=fmtp:123 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=640032\r\n' +
    'a=rtpmap:118 rtx/90000\r\n' +
    'a=fmtp:118 apt=123\r\n' +
    'a=rtpmap:114 red/90000\r\n' +
    'a=rtpmap:115 rtx/90000\r\n' +
    'a=fmtp:115 apt=114\r\n' +
    'a=rtpmap:116 ulpfec/90000\r\n' +
    'a=ssrc-group:FID 3194951553 658670364\r\n' +
    'a=ssrc:3194951553 cname:C9N45apy7vfT4Waq\r\n' +
    'a=ssrc:3194951553 msid:VLvw0Ec4NwiXKVzTZyzl1m5aSLGW9EPe50Mz 95173d41-de5c-4864-8745-a8573f23f3d8\r\n' +
    'a=ssrc:3194951553 mslabel:VLvw0Ec4NwiXKVzTZyzl1m5aSLGW9EPe50Mz\r\n' +
    'a=ssrc:3194951553 label:95173d41-de5c-4864-8745-a8573f23f3d8\r\n' +
    'a=ssrc:658670364 cname:C9N45apy7vfT4Waq\r\n' +
    'a=ssrc:658670364 msid:VLvw0Ec4NwiXKVzTZyzl1m5aSLGW9EPe50Mz 95173d41-de5c-4864-8745-a8573f23f3d8\r\n' +
    'a=ssrc:658670364 mslabel:VLvw0Ec4NwiXKVzTZyzl1m5aSLGW9EPe50Mz\r\n' +
    'a=ssrc:658670364 label:95173d41-de5c-4864-8745-a8573f23f3d8\r\n'
}

  • Answer SDP 消息

 {
  type: 'answer',
  sdp: 'v=0\r\n' +
    'o=- 6808421739235470893 2 IN IP4 127.0.0.1\r\n' +
    's=-\r\n' +
    't=0 0\r\n' +
    'a=group:BUNDLE 0 1\r\n' +
    'a=extmap-allow-mixed\r\n' +
    'a=msid-semantic: WMS\r\n' +
    'm=audio 9 UDP/TLS/RTP/SAVPF 111 103 104 9 0 8 106 105 13 110 112 113 126\r\n' +
    'c=IN IP4 0.0.0.0\r\n' +
    'a=rtcp:9 IN IP4 0.0.0.0\r\n' +
    'a=ice-ufrag:8fbZ\r\n' +
    'a=ice-pwd:r/ZnPQzn6uh8LIKW1gfaacu6\r\n' +
    'a=ice-options:trickle\r\n' +
    'a=fingerprint:sha-256 3A:5E:40:E4:BD:31:64:74:86:41:5A:62:1B:CA:0A:0A:4A:A4:0D:59:68:D5:47:15:B6:53:FE:BE:0F:3C:8D:D6\r\n' +
    'a=setup:active\r\n' +
    'a=mid:0\r\n' +
    'a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level\r\n' +
    'a=extmap:2 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time\r\n' +
    'a=extmap:3 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01\r\n' +
    'a=extmap:4 urn:ietf:params:rtp-hdrext:sdes:mid\r\n' +
    'a=extmap:5 urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id\r\n' +
    'a=extmap:6 urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id\r\n' +
    'a=recvonly\r\n' +
    'a=rtcp-mux\r\n' +
    'a=rtpmap:111 opus/48000/2\r\n' +
    'a=rtcp-fb:111 transport-cc\r\n' +
    'a=fmtp:111 minptime=10;useinbandfec=1\r\n' +
    'a=rtpmap:103 ISAC/16000\r\n' +
    'a=rtpmap:104 ISAC/32000\r\n' +
    'a=rtpmap:9 G722/8000\r\n' +
    'a=rtpmap:0 PCMU/8000\r\n' +
    'a=rtpmap:8 PCMA/8000\r\n' +
    'a=rtpmap:106 CN/32000\r\n' +
    'a=rtpmap:105 CN/16000\r\n' +
    'a=rtpmap:13 CN/8000\r\n' +
    'a=rtpmap:110 telephone-event/48000\r\n' +
    'a=rtpmap:112 telephone-event/32000\r\n' +
    'a=rtpmap:113 telephone-event/16000\r\n' +
    'a=rtpmap:126 telephone-event/8000\r\n' +
    'm=video 9 UDP/TLS/RTP/SAVPF 102 121 127 120 125 107 108 109 124 119 123 118 114 115 116\r\n' +
    'c=IN IP4 0.0.0.0\r\n' +
    'a=rtcp:9 IN IP4 0.0.0.0\r\n' +
    'a=ice-ufrag:8fbZ\r\n' +
    'a=ice-pwd:r/ZnPQzn6uh8LIKW1gfaacu6\r\n' +
    'a=ice-options:trickle\r\n' +
    'a=fingerprint:sha-256 3A:5E:40:E4:BD:31:64:74:86:41:5A:62:1B:CA:0A:0A:4A:A4:0D:59:68:D5:47:15:B6:53:FE:BE:0F:3C:8D:D6\r\n' +
    'a=setup:active\r\n' +
    'a=mid:1\r\n' +
    'a=extmap:14 urn:ietf:params:rtp-hdrext:toffset\r\n' +
    'a=extmap:2 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time\r\n' +
    'a=extmap:13 urn:3gpp:video-orientation\r\n' +
    'a=extmap:3 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01\r\n' +
    'a=extmap:12 http://www.webrtc.org/experiments/rtp-hdrext/playout-delay\r\n' +
    'a=extmap:11 http://www.webrtc.org/experiments/rtp-hdrext/video-content-type\r\n' +
    'a=extmap:7 http://www.webrtc.org/experiments/rtp-hdrext/video-timing\r\n' +
    'a=extmap:8 http://www.webrtc.org/experiments/rtp-hdrext/color-space\r\n' +
    'a=extmap:4 urn:ietf:params:rtp-hdrext:sdes:mid\r\n' +
    'a=extmap:5 urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id\r\n' +
    'a=extmap:6 urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id\r\n' +
    'a=recvonly\r\n' +
    'a=rtcp-mux\r\n' +
    'a=rtcp-rsize\r\n' +
    'a=rtpmap:102 H264/90000\r\n' +
    'a=rtcp-fb:102 goog-remb\r\n' +
    'a=rtcp-fb:102 transport-cc\r\n' +
    'a=rtcp-fb:102 ccm fir\r\n' +
    'a=rtcp-fb:102 nack\r\n' +
    'a=rtcp-fb:102 nack pli\r\n' +
    'a=fmtp:102 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42001f\r\n' +
    'a=rtpmap:121 rtx/90000\r\n' +
    'a=fmtp:121 apt=102\r\n' +
    'a=rtpmap:127 H264/90000\r\n' +
    'a=rtcp-fb:127 goog-remb\r\n' +
    'a=rtcp-fb:127 transport-cc\r\n' +
    'a=rtcp-fb:127 ccm fir\r\n' +
    'a=rtcp-fb:127 nack\r\n' +
    'a=rtcp-fb:127 nack pli\r\n' +
    'a=fmtp:127 level-asymmetry-allowed=1;packetization-mode=0;profile-level-id=42001f\r\n' +
    'a=rtpmap:120 rtx/90000\r\n' +
    'a=fmtp:120 apt=127\r\n' +
    'a=rtpmap:125 H264/90000\r\n' +
    'a=rtcp-fb:125 goog-remb\r\n' +
    'a=rtcp-fb:125 transport-cc\r\n' +
    'a=rtcp-fb:125 ccm fir\r\n' +
    'a=rtcp-fb:125 nack\r\n' +
    'a=rtcp-fb:125 nack pli\r\n' +
    'a=fmtp:125 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f\r\n' +
    'a=rtpmap:107 rtx/90000\r\n' +
    'a=fmtp:107 apt=125\r\n' +
    'a=rtpmap:108 H264/90000\r\n' +
    'a=rtcp-fb:108 goog-remb\r\n' +
    'a=rtcp-fb:108 transport-cc\r\n' +
    'a=rtcp-fb:108 ccm fir\r\n' +
    'a=rtcp-fb:108 nack\r\n' +
    'a=rtcp-fb:108 nack pli\r\n' +
    'a=fmtp:108 level-asymmetry-allowed=1;packetization-mode=0;profile-level-id=42e01f\r\n' +
    'a=rtpmap:109 rtx/90000\r\n' +
    'a=fmtp:109 apt=108\r\n' +
    'a=rtpmap:124 H264/90000\r\n' +
    'a=rtcp-fb:124 goog-remb\r\n' +
    'a=rtcp-fb:124 transport-cc\r\n' +
    'a=rtcp-fb:124 ccm fir\r\n' +
    'a=rtcp-fb:124 nack\r\n' +
    'a=rtcp-fb:124 nack pli\r\n' +
    'a=fmtp:124 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=4d0015\r\n' +
    'a=rtpmap:119 rtx/90000\r\n' +
    'a=fmtp:119 apt=124\r\n' +
    'a=rtpmap:123 H264/90000\r\n' +
    'a=rtcp-fb:123 goog-remb\r\n' +
    'a=rtcp-fb:123 transport-cc\r\n' +
    'a=rtcp-fb:123 ccm fir\r\n' +
    'a=rtcp-fb:123 nack\r\n' +
    'a=rtcp-fb:123 nack pli\r\n' +
    'a=fmtp:123 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=640015\r\n' +
    'a=rtpmap:118 rtx/90000\r\n' +
    'a=fmtp:118 apt=123\r\n' +
    'a=rtpmap:114 red/90000\r\n' +
    'a=rtpmap:115 rtx/90000\r\n' +
    'a=fmtp:115 apt=114\r\n' +
    'a=rtpmap:116 ulpfec/90000\r\n'
}

Wireshark 抓包

1.首先安裝wireshark軟件厢汹,這個(gè)地球人都知道

2.用wireshark抓取H264視頻碼流螟深,最好過濾掉其他碼流

3.右鍵點(diǎn)擊H264的udp包,選擇"Decode as..."烫葬,再選擇Transport中的rtp選項(xiàng)界弧,就解析成rtp包了

4.查看rtp包的payload type,比如說type是 102搭综,那么在wireshark工具欄選擇Edit->preferences->protocols->H264, 把H264 dynamic payload types設(shè)成 102

  • RTP 流
  • RTP 包


  • H.264 荷載

  1. SPS
  1. FU-A
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末垢箕,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子兑巾,更是在濱河造成了極大的恐慌条获,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,639評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件闪朱,死亡現(xiàn)場離奇詭異月匣,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)奋姿,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,277評論 3 385
  • 文/潘曉璐 我一進(jìn)店門锄开,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人称诗,你說我怎么就攤上這事萍悴。” “怎么了寓免?”我有些...
    開封第一講書人閱讀 157,221評論 0 348
  • 文/不壞的土叔 我叫張陵癣诱,是天一觀的道長。 經(jīng)常有香客問我袜香,道長撕予,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,474評論 1 283
  • 正文 為了忘掉前任蜈首,我火速辦了婚禮实抡,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘欢策。我一直安慰自己吆寨,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,570評論 6 386
  • 文/花漫 我一把揭開白布踩寇。 她就那樣靜靜地躺著啄清,像睡著了一般。 火紅的嫁衣襯著肌膚如雪俺孙。 梳的紋絲不亂的頭發(fā)上辣卒,一...
    開封第一講書人閱讀 49,816評論 1 290
  • 那天掷贾,我揣著相機(jī)與錄音,去河邊找鬼添寺。 笑死胯盯,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的计露。 我是一名探鬼主播博脑,決...
    沈念sama閱讀 38,957評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼票罐!你這毒婦竟也來了叉趣?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,718評論 0 266
  • 序言:老撾萬榮一對情侶失蹤该押,失蹤者是張志新(化名)和其女友劉穎疗杉,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蚕礼,經(jīng)...
    沈念sama閱讀 44,176評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡烟具,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,511評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了奠蹬。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片朝聋。...
    茶點(diǎn)故事閱讀 38,646評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖囤躁,靈堂內(nèi)的尸體忽然破棺而出冀痕,到底是詐尸還是另有隱情,我是刑警寧澤狸演,帶...
    沈念sama閱讀 34,322評論 4 330
  • 正文 年R本政府宣布言蛇,位于F島的核電站,受9級特大地震影響宵距,放射性物質(zhì)發(fā)生泄漏腊尚。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,934評論 3 313
  • 文/蒙蒙 一满哪、第九天 我趴在偏房一處隱蔽的房頂上張望婿斥。 院中可真熱鬧,春花似錦翩瓜、人聲如沸受扳。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,755評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至峡蟋,卻和暖如春坟桅,著一層夾襖步出監(jiān)牢的瞬間华望,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,987評論 1 266
  • 我被黑心中介騙來泰國打工仅乓, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留赖舟,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,358評論 2 360
  • 正文 我出身青樓夸楣,卻偏偏與公主長得像宾抓,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子豫喧,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,514評論 2 348

推薦閱讀更多精彩內(nèi)容