這個項目基於kurento tutorial的hello world構建。
項目地址:https://github.com/godka/kurento-rtmp
sdp參考:https://www.cnblogs.com/bigben0123/p/14229018.html
sdp是個文本文件,vlc拿到後可以直接直播。
使用技術包括c編譯生成的kurento webrtc服務;nodejs充當web服務接收websocket的sdp交換;nodejs同時啓動了node內置的流媒體服務node_media_server。
原理是攝像頭採集webRTC的,發送到kurento服務器。nodejs server充當kurento的客戶端,接收sdp offer,根據offer生成自定義得sdp,ffmpeg將sdp和rtp://xxx內容用rtmp推到流媒體服務器node_media_server.
(
sdp是描述RTP包的信息包文件,需要手動加入時間戳等信息,並且在打包rtp時填寫。代碼實現是,你調用ffmpeg庫的函數接口,打包sdp頭信息,並將視頻數據打包稱rtp,然後發送到http://xxxxxx
udp:
推送:ffmpeg -re -i test.264 -vcodec copy -f h264 udp://10.0.192.82:6970
拉取:ffplay -f h264 udp://10.0.192.82:6970
rtp:
ffmpeg -re -i test.264 -vcodec copy -f rtp rtp://10.0.192.82:6970>test.sdp
ffplay test.sdp
)
從頁面採集攝像頭數據用webRTC,通過ws發送到服務端。在 webRtcEndpoint.processOffer處理客戶端發來得sdp offer。我們自己生成 rtp的sdpRtpOfferString,將它傳遞給rtp的
-
構建:
1.install node && npm 需要nodejs npm安裝:https://www.cnblogs.com/schips/p/12402412.html
2.git clone https://github.com/godka/kurento-rtmp
3.cd kurento-rtmp
4.npm install
5.node server.js
6.Open https://yourhost:8443 on Chrome or Firefox
7.Click Start button and have fun!
也可以參考kurento tutorial的hello world安裝:
Be sure to install Bower and Node.js version 8.x in your system. In an Ubuntu machine, you can install both as follows:
curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -
sudo apt-get install -y nodejs
sudo npm install -g bower
Also, Node.js should already include NPM, the Node.js package manager.
To launch the application, you need to clone the GitHub project where this demo is hosted, install it and run it:
git clone https://github.com/Kurento/kurento-tutorial-node.git
cd kurento-tutorial-node/kurento-hello-world
git checkout master
npm install
cd static
bower install --allow-root
cd ..
npm start
If you have problems installing any of the dependencies, please remove them and clean the npm cache, and try to install them again:
rm -r node_modules
npm cache clean
Access the application connecting to the URL https://localhost:8443/ in a WebRTC capable browser (Chrome, Firefox).
Note
These instructions work only if Kurento Media Server is up and running in the same machine as the tutorial. However, it is possible to connect to a remote KMS in other machine, simply adding the argument ws_uri
to the npm execution command, as follows:
npm start -- --ws_uri=ws://{KMS_HOST}:8888/kurento
In this case you need to use npm version 2. To update it you can use this command:
sudo npm install npm -g
觀看rmtp地址:
啓動後,推webrtc地址:https://localhost:8443/.
如果不能回顯,去https://ossrs.net/players/srs_player.html,在srs播放器裏面地址輸入:rtmp://192.168.16.133/live/127.0.0.1_55002,可以播放。地址是從下面log中找到的:
修改server.js,推流地址變成rtmp://192.168.16.133/live/55002,去掉127.0.0.1_
不用搭建srs,直接用播放器訪問http flv地址,即可播放:http://192.168.16.133:8000/live/55002.flv
server.js是服務器. 這個開源用了Node-Media-Server。它是支持rtmp,http flv等的流媒體服務器。
ffmpeg推流用的命令 用sdp生成rtp命令
/*ffmpeg -protocol_whitelist "file,udp,rtp" -i test.sdp -vcodec copy -f flv rtmp://localhost/live/stream */ /* SDP: v=0 o=- 0 0 IN IP4 127.0.0.1 s=No Name c=IN IP4 127.0.0.1 t=0 0 a=tool:libavformat 57.71.100 m=video 55000 RTP/AVP 96 b=AS:200 a=rtpmap:96 H264/90000 */
實現回顯:webrtc連接成功後,rtp再去回連webrtc。這樣就回顯。
function connectMediaElements(webRtcEndpoint, rtpEndpoint, callback) {
webRtcEndpoint.connect(rtpEndpoint, function (error) {
if (error) {
return callback(error);
}
rtpEndpoint.connect(webRtcEndpoint, function (error) {//rtpEndPoint又連接回去webRTC
if (error) {
return callback(error);
}
return callback(null);
});
});
}
配置sdpStream類型, H264,這裏時爲了生成 rtp
function generateSdpStreamConfig(nodeStreamIp, port, callback) {
... ...
var sdpRtpOfferString = 'v=0\n';
sdpRtpOfferString += 'o=- 0 0 IN IP4 ' + nodeStreamIp + '\n';
sdpRtpOfferString += 's=KMS\n';
sdpRtpOfferString += 'c=IN IP4 ' + nodeStreamIp + '\n';
sdpRtpOfferString += 't=0 0\n';
sdpRtpOfferString += 'm=video ' + port + ' RTP/AVP 96\n';
sdpRtpOfferString += 'a=rtpmap:96 H264/90000\n';
sdpRtpOfferString += 'a=fmtp:96 packetization-mode=1\n';
return callback(null, sdpRtpOfferString);
增加音頻處理部分
sdpRtpOfferString += 'm=audio 49170 RTP/AVP 97\n' ;
sdpRtpOfferString += 'a=recvonly\n' ;
sdpRtpOfferString += 'a=rtpmap:97 PCMU/8000\n' ;
sdpRtpOfferString += 'a=fmtp:97 profile-level-id=1;mode=AAC-hbr;sizelength=13;indexlength=3;indexdeltalength=3;config=1508\n' ;
在rtpEndpoint.processOffer去使用:
webrtc連接成功 => rtc.processOffer => 成功後按照sdp config 調用 rtp.processOffer =>callback(sdpanswer):
webRtcEndpoint.processOffer(sdpOffer, function (error, sdpAnswer) { if (error) { pipeline.release(); return callback(error); } sessions[sessionId] = { 'pipeline': pipeline, 'webRtcEndpoint': webRtcEndpoint } var streamPort = 55000;
//每個新session會調用這裏一次
var streamIp = '127.0.0.1';//Test ip generateSdpStreamConfig(streamIp, streamPort, function (err, sdpRtpOfferString) { if (err) { return callback(error); } rtpEndpoint.processOffer(sdpRtpOfferString, function (error) { if (error) { return callback(error); } console.log('start process on: rtp://' + streamIp + ':' + streamPort); console.log('recv sdp answer:', sdpAnswer);
bindFFmpeg(streamIp, streamPort, sdpRtpOfferString, ws) return callback(null, sdpAnswer); }); }); })
加入session 和 ffmpeg:
全局
var session_index = 0;
用戶連接端口生成:
//對於RTP,偶數端口被用來傳輸數據,奇數端口用來傳輸RTCP包
var streamPort = 55000 + (session_index * 2);
var audioPort = 49170 + (session_index * 2);
session_index++; //change to next port
webRtcEndpoint.setMaxVideoRecvBandwidth(200)
node-media-server加入rtmp,flv
const NodeMediaServer = require('node-media-server').NodeMediaServer
const rtmp_server_config = {
rtmp: {
port: 1935,
chunk_size: 60000,
gop_cache: true,
ping: 60,
ping_timeout: 30
},
http: {
port: 8000,
allow_origin: '*'
}
};
var nms = new NodeMediaServer(rtmp_server_config);
nms.run();
整體流程圖:
瀏覽器console log
nodejs server.js日誌輸出