Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 91成人国产网站在线观看,青青草国产免费久久久91,三级在线观看国产

          整合營銷服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢熱線:

          手把手配置HLS流媒體服務(wù)器

          讀本文前,務(wù)必先閱讀前面這篇文章,手把手搭建流媒體服務(wù)器詳細(xì)步驟。因?yàn)楸酒恼率窃谶@篇文章的基礎(chǔ)上搭建。

          1.HLS簡述

          HLS是Apple 提出的?種基于 HTTP 的協(xié)議,HLS(HTTP Live Streaming)?于解決實(shí)時?視頻流的傳輸。尤其是在ios移動端,由于 iOS /H5 不?持 flash,使得 HLS 成了ios移動端實(shí)時視頻流傳輸?shù)?選。HLS經(jīng)常?在直播領(lǐng)域,?些國內(nèi)的直播云通常? HLS 拉流(將視頻流從服務(wù)器拉到客戶端)。HLS最大的缺點(diǎn)就是延遲嚴(yán)重,延遲通常在10-30s 之間。

          英文本協(xié)議地址如下,可以詳細(xì)閱讀。

          HLS英文版協(xié)議:https://tools.ietf.org/html/draft-pantos-http-live-streaming-06

          協(xié)議有如下部分:

          蘋果開發(fā)者官網(wǎng):https://developer.apple.com/streaming/


          2.HLS數(shù)據(jù)流整體框架

          HLS數(shù)據(jù)流向的整體框架如下圖所示。其主要分為以下幾步:

          (1)推流端把采集,編碼,封裝的數(shù)據(jù)數(shù)據(jù)發(fā)送到服務(wù)端。

          (2)Stream segmenter是指把碼流分片。對直播或點(diǎn)播流進(jìn)行分片,分片的數(shù)量是固定,每個分片的時長也是固定,如5個分片,每個分片為5s,分片時間沒有辦法精確到毫秒,因?yàn)榉制话隳J(rèn)都是從I幀開始,保證一個完整的GOP。如果分配數(shù)量為5,那么就是最多緩存5個分片,只會保存最新分片,過時的分片就會刪除。如有當(dāng)前有1個分片。當(dāng)?shù)?個分片加進(jìn)來,則第一個分片就會被刪除。

          (3)index file就是存儲目前的分片信息,如把分片1,分片2寫入index file。如下圖:

          (4)推送給web server,然后存儲ts文件。

          (5)通過HTTP協(xié)議讀取服務(wù)器文件,先讀取index file,然后解析index file,最后讀取相應(yīng)的ts文件。服務(wù)器就把ts文件送出去,然后 播放。

          (6)因?yàn)閕ndex file是保存分片信息,分片是實(shí)時更新,所以index file也是持續(xù)更新。只要有新的ts文件生成那就會更新。每次index file的ts文件讀取完畢,就會再次讀取index file文件,獲取新的index file,繼續(xù)讀取最新的ts文件,如此往復(fù)。


          3.搭建HLS流媒體服務(wù)器

          先參考前面這篇文章:手把手搭建流媒體服務(wù)器詳細(xì)步驟

          下面前面2步,在這篇文章手把手搭建流媒體服務(wù)器詳細(xì)步驟有詳細(xì)說明。

          (1)srs官?:https://github.com/ossrs/srs

          碼云的源速度快:https://gitee.com/winlinvip/srs.oschina.git

          github的源速度慢:https://github.com/ossrs/srs.git

          選擇當(dāng)前最新的release版本3.0

          第?步,獲取SRS。詳細(xì)參考GIT獲取代碼:https://github.com/ossrs/srs/wiki/v1_CN_Git

          git clone https://gitee.com/winlinvip/srs.oschina.git
          
          cd srs.oschina
          
          cd trunk

          第?步,編譯SRS。詳細(xì)參考Build:https://github.com/ossrs/srs/wiki/v3_CN_Build

          ./configure && make

          (3)編寫SRS配置?件。詳細(xì)參考RTMP分發(fā):https://github.com/ossrs/srs/wiki/v1_CN_DeliveryRTMP,Delivery HLS:https://github.com/ossrs/srs/wiki/v3_CN_SampleHLS,Delivery HTTP FLV:https://github.com/ossrs/srs/wiki/v3_CN_SampleHttpFlv,編輯 conf/srs.conf (尤其是hls和http_remux部分),服務(wù)器啟動時指定該配置?件(srs的conf?件夾有該?件)。

          listen              1935;
          max_connections     1000;
          srs_log_tank        file;
          srs_log_file        ./objs/srs.log;
          http_api {
              enabled         on;
              listen          1985;
          }
          http_server {
              enabled         on;
              listen          8080;#改為8081應(yīng)該也可以
              dir             ./objs/nginx/html;
          }
          stats {
              network         0;
              disk            sda sdb xvda xvdb;
          }
          vhost __defaultVhost__ {
                  #hls antonio
                  hls{
                  enabled on;
                  hls_path ./objs/nginx/html;#生成ts文件路經(jīng)
                  hls_fragment 5; # 分?時? 秒
                  hls_window 25; # 最?緩存的時?秒,也決定了最大延遲時間
          }
                  #http-flv for antonio
                  http_remux
                  {
                  enabled on;
                  mount [vhost]/[app]/[stream].flv;
                  hstrs on;
                  }
          }
          

          (4)啟動SRS。

          -c表示是讀取配置文件。

          在這個路經(jīng)執(zhí)行:


          ./objs/srs -c conf/srs.conf

          出現(xiàn)如下,就代表通過后臺跑起來了。


          也可以再輸入如下命令,讓其在前臺顯示,并查看log信息:

          在如下目錄:

          前臺查看log命令如下:

          tail -f objs/srs.log

          出現(xiàn)如下,代表可以成功查看信息:

          使用ffmpeg推流一定要搭建好ffmpeg環(huán)境以及到帶有xxx.flv文件的指定目錄去執(zhí)行命令。

          ffmpeg推流:ffmpeg -re -i source.200kbps.768x320.flv -vcodec copy -acodec copy -f flv -y

          拉流:ffplay rtmp://172.16.204.132/live/livestream

          注意:上述命令中的flv完整路徑,以及srs server ip,?家根據(jù)情況??替換為實(shí)際值。 另外:默認(rèn)情況下srs的rtmp采?1935端?,如果該端?被占?或修改了srs.conf中的端?,注意根據(jù)情況調(diào)整;防?墻如果開了,也要檢測下1935是否允許訪問。

          出現(xiàn)如下界面,就代表搭建成功。


          十分注意:很多朋友都沒注意一個概念,就是以為hls有推流端,實(shí)時是hls只有拉流的說法。


          (5)拉流RTMP/HLS/HTTP-FLV流

          RTMP拉流地址:ffplay rtmp://172.16.204.132/live/livestream

          HTTP FLV拉流地址:ffplay http://172.16.204.132:8080/live/livestream.flv

          HLS拉流地址:ffplay http://172.16.204.132:8080/live/livestream.m3u8


          同時拉流端也可以使用可以使?ffplay或者vlc以及 http://ossrs.net/srs.release/trunk/research/players/srs_player.html(經(jīng)過測試這個播放器也是能拉取到各類流)或其它拉流工具進(jìn)?測試。


          對比延時時間:

          對比拉取RTMP流和http的livestream.m3u8流。其中左圖是RTMP流,右圖是livestream.m3u8流,可以看出HLS相較RTMP,延時多了接近16s左右,hls這個延時就是最大確點(diǎn)。

          另外,經(jīng)過測試,拉流FLV這個也是ffplay http://172.16.204.132:8080/live/livestream.flv,也是能夠拉取到。

          本篇文章就分析到這里,歡迎大家關(guān)注歡迎關(guān)注,點(diǎn)贊,轉(zhuǎn)發(fā),收藏,分享,評論區(qū)討論。

          后面關(guān)于項(xiàng)目知識,后期會更新。歡迎關(guān)注微信公眾號"記錄世界 from antonio"。

          RS環(huán)境搭建

          srs官網(wǎng):SRS官網(wǎng)

          碼云的源速度快:碼云的源速度快

          github的源速度慢:github的源速度慢

          選擇當(dāng)前最新的release版本3.0

          第一步,獲取SRS。詳細(xì)參考GIT獲取代碼

          git clone https://gitee.com/winlinvip/srs.oschina.git srs.3.0-20200720

          cd srs.3.0-20200720

          #使?當(dāng)前最新的3.0版本

          git checkout 3.0release

          cd trunk

          第二步,編譯SRS。詳細(xì)參考Build

          ./configure && make

          第三步,編寫SRS配置文件。詳細(xì)參考RTMP分發(fā),Delivery HLS,Delivery HTTP FLV

          編輯 conf/srs.conf ,服務(wù)器啟動時指定該配置文件(srs的conf文件夾有該文件)。

          1 listen 1935;
          2 max_connections 1000;
          3 srs_log_tank file;
          4 srs_log_file ./objs/srs.log;
          5 http_api {
          6 enabled on;
          7 listen 1985;
          8 }
          9 http_server {
          10 enabled on;
          11 listen 8081; # http監(jiān)聽端?,注意??配置的端?
          12 dir ./objs/nginx/html;
          13 }
          14 stats {
          15 network 0;
          16 disk sda sdb xvda xvdb;
          17 }
          18 vhost __defaultVhost__ {
          19 # hls darren
          20 hls {
          21 enabled on;
          22 hls_path ./objs/nginx/html;
          23 hls_fragment 10;
          24 hls_window 60;
          25 }
          26 # http-flv darren
          27 http_remux {
          28 enabled on;
          29 mount [vhost]/[app]/[stream].flv;
          30 hstrs on;
          31 }
          32 }


          SRS全網(wǎng)獨(dú)一份的視頻文檔資料私信1,進(jìn)群免費(fèi)領(lǐng)取,更有【免費(fèi)】FFmpeg/WebRTC/RTMP/NDK/Android音視頻流媒體高級開發(fā)-學(xué)習(xí)視頻教程-騰訊課堂

          第四步,啟動SRS。

          ./objs/srs -c conf/srs.conf

          1 ubuntu@VM-0-13-ubuntu:~/0voice/media/srs.3.0-20200720/trunk$ ./objs/s
          2rs -c conf/srs.conf
          2 后臺運(yùn)?結(jié)果
          3 [2020-07-20 17:34:48.061][Trace][30433][0] XCORE-SRS/3.0.141(OuXuli)
          4 [2020-07-20 17:34:48.061][Trace][30433][0] config parse complete
          5 [2020-07-20 17:34:48.061][Trace][30433][0] write log to file ./objs/s
          rs.log
          6 [2020-07-20 17:34:48.061][Trace][30433][0] you can: tailf ./objs/srs.
          log
          7 [2020-07-20 17:34:48.061][Trace][30433][0] @see: https://github.com/o
          ssrs/srs/wiki/v1_CN_SrsLog

          確認(rèn)是否已經(jīng)正常啟動

          1 ubuntu@VM-0-13-ubuntu:~/0voice/media/srs.3.0-20200720/trunk$ sudo ps
          -ef | grep srs
          2 ubuntu 30435 1 0 17:34 pts/0 00:00:00 ./objs/srs -c conf/sr
          s.conf

          顯示到ubuntu 30435 1 0 17:34 pts/0 00:00:00 ./objs/srs -c conf/srs.conf

          安全退出正在運(yùn)行的srs

          sudo kill -SIGQUIT srs_pid

          默認(rèn)是后臺啟動的方式,如果是要方便GDB調(diào)試則需要修改配置文件為前臺啟動。

          1 listen 1935;
          2 max_connections 1000;
          3 #srs_log_tank file;
          4 #srs_log_file ./objs/srs.log;
          5 # 前臺運(yùn)?
          6 daemon off;
          7 # 打印到終端控制臺
          8 srs_log_tank console;
          9 http_api {
          10 enabled on;
          11 listen 1985;
          12 }
          313 http_server {
          14 enabled on;
          15 listen 8081; # http監(jiān)聽端?
          16 dir ./objs/nginx/html;
          17 }
          18 stats {
          19 network 0;
          20 disk sda sdb xvda xvdb;
          21 }
          22 vhost __defaultVhost__ {
          23 # hls darren
          24 hls {
          25 enabled on;
          26 hls_path ./objs/nginx/html;
          27 hls_fragment 10;
          28 hls_window 60;
          29 }
          30 # http-flv darren
          31 http_remux {
          32 enabled on;
          33 mount [vhost]/[app]/[stream].flv;
          34 hstrs on;
          35 }
          36 }

          執(zhí)行方法:./objs/srs -c conf/srs.conf

          在終端運(yùn)行,log也在終端顯示

          1 [2020-07-20 17:46:33.586][Trace][1533][0] system default latency(ms)
          : mw(0-350) + mr(0-350) + play-queue(0-30000)
          2 [2020-07-20 17:46:33.586][Warn][1533][0][0] SRS/3.0.141 is beta
          3 [2020-07-20 17:46:33.586][Trace][1533][0] http flv live stream, vhos
          t=__defaultVhost__, mount=[vhost]/[app]/[stream].flv
          4 [2020-07-20 17:46:33.586][Trace][1533][0] http: root mount to ./objs
          /nginx/html
          5 [2020-07-20 17:46:33.586][Trace][1533][0] st_init success, use epoll
          6 [2020-07-20 17:46:33.586][Trace][1533][380] server main cid=380, pid
          45
          =1533, ppid=2337, asprocess=0
          7 [2020-07-20 17:46:33.586][Trace][1533][380] write pid=1533 to ./objs
          /srs.pid success!
          8 [2020-07-20 17:46:33.586][Trace][1533][380] RTMP listen at tcp://0.0
          .0.0:1935, fd=7
          9 [2020-07-20 17:46:33.586][Trace][1533][380] HTTP-API listen at tcp:/
          /0.0.0.0:1985, fd=8
          10 [2020-07-20 17:46:33.586][Trace][1533][380] HTTP-Server listen at tc
          p://0.0.0.0:8081, fd=9
          11 [2020-07-20 17:46:33.586][Trace][1533][380] signal installed, reload
          =1, reopen=10, fast_quit=15, grace_quit=3
          12 [2020-07-20 17:46:33.586][Trace][1533][380] http: api mount /console
          to ./objs/nginx/html/console

          SRS源碼目錄

          trunk目錄

          3rdparty auto conf configure doc etc ide modules research scripts src usr

          src下的源碼

          app core kernel libs main protocol service utest

          app應(yīng)用

          ├── app

          │ ├── srs_app_async_call.cpp

          │ ├── srs_app_async_call.hpp 可以用來執(zhí)行異步任務(wù),通過execute()函數(shù) push任務(wù),然后

          在cycle()執(zhí)行

          │ ├── srs_app_bandwidth.cpp

          │ ├── srs_app_bandwidth.hpp 提供帶寬測試接口

          │ ├── srs_app_caster_flv.cpp

          │ ├── srs_app_caster_flv.hpp 支持POST一個flv流到服務(wù)器,類似相當(dāng)于RTMP的publish

          │ ├── srs_app_config.cpp

          │ ├── srs_app_config.hpp 讀取配置文件

          │ ├── srs_app_conn.cpp

          │ ├── srs_app_conn.hpp srs的基本連接,每個連接對應(yīng)一個協(xié)程,所有的連接都被管理

          │ ├── srs_app_coworkers.cpp

          │ ├── srs_app_coworkers.hpp SrsCoWorkers For origin cluster

          │ ├── srs_app_dash.cpp

          │ ├── srs_app_dash.hpp SrsDash 流媒體DASH業(yè)務(wù) The MPEG-DASH encoder,

          transmux RTMP to DASH.

          │ ├── srs_app_dvr.cpp

          │ ├── srs_app_dvr.hpp SrsDvr 錄制RTMP流程flv或者mp4文件

          │ ├── srs_app_edge.cpp

          │ ├── srs_app_edge.hpp SrsEdgeRtmpUpstream 邊緣節(jié)點(diǎn)業(yè)務(wù),比如從源站拉流到邊緣,邊

          緣回溯到源站

          │ ├── srs_app_empty.cpp

          │ ├── srs_app_empty.hpp 沒有內(nèi)容

          │ ├── srs_app_encoder.cpp

          │ ├── srs_app_encoder.hpp SrsEncoder 可以使用多個ffmpeg來轉(zhuǎn)換指定的流,最終調(diào)用

          SrsFFMPEG來轉(zhuǎn)流

          │ ├── srs_app_ffmpeg.cpp

          │ ├── srs_app_ffmpeg.hpp SrsFFMPEG 使用ffmpeg來轉(zhuǎn)換流

          │ ├── srs_app_forward.cpp

          │ ├── srs_app_forward.hpp SrsForwarder 將流轉(zhuǎn)發(fā)到其他服務(wù)器

          │ ├── srs_app_fragment.cpp

          │ ├── srs_app_fragment.hpp SrsFragment 表示一個分片,如HLS分片、DVR分片或DASH分

          片。它是一個媒體文件,例如FLV或MP4,有持續(xù)時間。

          │ ├── srs_app_hds.cpp

          │ ├── srs_app_hds.hpp SrsHds 將RTMP轉(zhuǎn)成Adobe HDS流

          │ ├── srs_app_heartbeat.cpp

          │ ├── srs_app_heartbeat.hpp SrsHttpHeartbeat HHTP心跳

          │ ├── srs_app_hls.cpp

          │ ├── srs_app_hls.hpp SrsHls HLS業(yè)務(wù),Transmux RTMP stream to HLS(m3u8 and

          ts).

          │├── srs_app_hourglass.cpp

          │ ├── srs_app_hourglass.hpp SrsHourGlass 滴答tick的處理程序

          │ ├── srs_app_http_api.cpp

          │ ├── srs_app_http_api.hpp SrsHttpApi HTTP業(yè)務(wù)API7

          │ ├── srs_app_http_client.cpp

          │ ├── srs_app_http_client.hpp 沒有內(nèi)容

          │ ├── srs_app_http_conn.cpp

          │ ├── srs_app_http_conn.hpp SrsHttpConn,HTTP連接,繼承于SrsConnection

          │ ├── srs_app_http_hooks.cpp

          │ ├── srs_app_http_hooks.hpp SrsHttpHooks HTTP勾子,HTTP回調(diào)API

          │ ├── srs_app_http_static.cpp

          │ ├── srs_app_http_static.hpp SrsHttpStaticServer HTTP靜態(tài)服務(wù)器實(shí)例,為HTTP靜態(tài)文

          件和FLV/MP4視頻點(diǎn)播服務(wù)

          │ ├── srs_app_http_stream.cpp

          │ ├── srs_app_http_stream.hpp SrsHttpStreamServer HTTP直播流服務(wù),支持

          FLV/TS/MP3/AAC流

          │ ├── srs_app_ingest.cpp

          │ ├── srs_app_ingest.hpp SrsIngester攝取文件/流/設(shè)備,用FFMPEG編碼(可選), 通過

          RTMP推送到SRS(或其他RTMP服務(wù)器)

          │ ├── srs_app_listener.cpp

          │ ├── srs_app_listener.hpp SrsTcpListener SrsUdpListener TCP/UDP監(jiān)聽器

          │ ├── srs_app_log.cpp

          │ ├── srs_app_log.hpp SrsFastLog 日志

          │ ├── srs_app_mpegts_udp.cpp

          │ ├── srs_app_mpegts_udp.hpp SrsMpegtsOverUdpThe mpegts over udp stream caster

          │ ├── srs_app_ng_exec.cpp

          │ ├── srs_app_ng_exec.hpp SrsNgExec

          │ ├── srs_app_pithy_print.cpp

          │ ├── srs_app_pithy_print.hpp SrsPithyPrint 收集信息,然后打印

          │ ├── srs_app_process.cpp

          │ ├── srs_app_process.hpp SrsProcess啟動和停止進(jìn)程,當(dāng)被終止時調(diào)用cycle重新啟動進(jìn)

          │ ├── srs_app_recv_thread.cpp

          │ ├── srs_app_recv_thread.hpp SrsHttpRecvThread HTTP數(shù)據(jù)讀取,

          SrsPublishRecvThread推流數(shù)據(jù)讀取,SrsQueueRecvThread從隊(duì)列讀取;SrsRecvThread封裝的協(xié)程

          │ ├── srs_app_refer.cpp

          │ ├── srs_app_refer.hpp SrsRefer

          │ ├── srs_app_reload.cpp

          │ ├── srs_app_reload.hpp ISrsReloadHandler 重新讀取配置文件的處理

          │ ├── srs_app_rtmp_conn.cpp

          │ ├── srs_app_rtmp_conn.hpp SrsRtmpConn RTMP連接

          │ ├── srs_app_rtsp.cpp

          │ ├── srs_app_rtsp.hpp SrsRtpConn RTSP連接,SrsRtspCaster RTSP業(yè)務(wù)

          │ ├── srs_app_security.cpp8

          │ ├── srs_app_security.hpp SrsSecurity 安全限制,主要是限制url

          │ ├── srs_app_server.cpp

          │ ├── srs_app_server.hpp SrsServer SRS服務(wù),對應(yīng)的rtmp、rtsp、http-flv等等業(yè)務(wù)在這里啟動

          │ ├── srs_app_source.cpp

          │ ├── srs_app_source.hpp SrsSource 對應(yīng)一個源,支持多個SrsConsumer來拉流,

          SrsSourceManager管理源, SrsMetaCache?于源緩存Meta數(shù)據(jù),SrsConsumer源的消費(fèi)者,

          SrsGopCache GOP緩存

          │ ├── srs_app_statistic.cpp

          │ ├── srs_app_statistic.hpp SrsStatistic流統(tǒng)計

          │ ├── srs_app_st.cpp

          │ ├── srs_app_st.hpp SrsSTCoroutine協(xié)程相關(guān)

          │ ├── srs_app_thread.cpp

          │ ├── srs_app_thread.hpp SrsCoroutineManager協(xié)程管理

          │ ├── srs_app_utility.cpp

          │ └── srs_app_utility.hpp 工具類:SrsPlatformInfo、SrsNetworkDevices、SrsMemInfo、

          SrsDiskStat等等

          ├── core

          │ ├── srs_core_autofree.cpp

          │ ├── srs_core_autofree.hpp 通過棧上的方式構(gòu)建自動釋放堆申請的對象,這個設(shè)計還是非常值

          得我們學(xué)習(xí)

          │ ├── srs_core.cpp

          │ ├── srs_core.hpp 版本相關(guān)的?些信息

          │ ├── srs_core_mem_watch.cpp

          │ ├── srs_core_mem_watch.hpp 內(nèi)存監(jiān)測接口

          │ ├── srs_core_performance.cpp

          │ ├── srs_core_performance.hpp 性能測試相關(guān)

          │ ├── srs_core_time.cpp

          │ ├── srs_core_time.hpp 時間單位相關(guān)

          │ ├── srs_core_version3.cpp

          │ └── srs_core_version3.hpp 版本信息

          ├── kernel // 音視頻格式相關(guān)的

          │ ├── srs_kernel_aac.cpp

          │ ├── srs_kernel_aac.hpp SrsAacTransmuxer 合成AAC音頻流,帶ADTS header

          │ ├── srs_kernel_balance.cpp

          │ ├── srs_kernel_balance.hpp SrsLbRoundRobin負(fù)載均衡,用于邊緣節(jié)點(diǎn)拉流和其他多個服

          務(wù)器的功能

          │ ├── srs_kernel_buffer.cpp

          │ ├── srs_kernel_buffer.hpp SrsBuffer讀取字節(jié)的實(shí)用類

          │ ├── srs_kernel_codec.cpp9

          │ ├── srs_kernel_codec.hpp 編碼器相關(guān),包括視頻和音頻,非常核心的文件;SrsFlvVideo用來檢測FLV的video tag對應(yīng)內(nèi)容;SrsFlvAudio用來檢測FLV的audio tag對應(yīng)內(nèi)容;SrsMaxNbSamples

          256表示video最大的NALUS個數(shù),audio最大的packet數(shù)量;SrsFrame存儲幀,SrsAudioFrame 存儲

          AAC幀,SrsVideoFrame存儲視頻幀;SrsFormat編碼器格式,包含了一個或者多個流,比如為RTMP

          format時,包含一個視頻和一個音頻幀。先猜測推流時的數(shù)據(jù)實(shí)例是保存在SrsFormat?

          │ ├── srs_kernel_consts.cpp

          │ ├── srs_kernel_consts.hpp SRS的常量定義,比如播放的標(biāo)記#define

          SRS_CONSTS_LOG_PLAY "PLA";發(fā)布的標(biāo)記#define SRS_CONSTS_LOG_CLIENT_PUBLISH

          "CPB";SRS_CONSTS_HTTP_XXX等HTTP響應(yīng)碼;SRS_CONSTS_RTSP_XXX響應(yīng)碼等等。

          │ ├── srs_kernel_error.cpp

          │ ├── srs_kernel_error.hpp 返回值常量定義,ERROR_XXX;SrsCplxError 異常類

          │ ├── srs_kernel_file.cpp

          │ ├── srs_kernel_file.hpp 文件的讀寫,SrsFileWriter文件寫入器,SrsFileReader文件讀取器

          │ ├── srs_kernel_flv.cpp

          │ ├── srs_kernel_flv.hpp FLV SrsFlvDecoder解析,SrsFlvTransmuxer將RTMP轉(zhuǎn)成FLV流;

          SrsSharedPtrMessage對應(yīng)RTMP的消息

          │ ├── srs_kernel_io.cpp

          │ ├── srs_kernel_io.hpp IO讀寫接口類

          │ ├── srs_kernel_log.cpp

          │ ├── srs_kernel_log.hpp 日志相關(guān)

          │ ├── srs_kernel_mp3.cpp

          │ ├── srs_kernel_mp3.hpp SrsMp3Transmuxer將RTMP轉(zhuǎn)成MP3流

          │ ├── srs_kernel_mp4.cpp

          │ ├── srs_kernel_mp4.hpp SrsMp4Encoder MP4復(fù)用器;

          │ ├── srs_kernel_stream.cpp

          │ ├── srs_kernel_stream.hpp SrsSimpleStream用vector實(shí)現(xiàn)的簡單的字節(jié)append類,主要在

          hls和http中使用,將來需要進(jìn)行改進(jìn)。

          │ ├── srs_kernel_ts.cpp

          │ ├── srs_kernel_ts.hpp SrsTsTransmuxer將RTMP流轉(zhuǎn)成http-ts流,該文件實(shí)現(xiàn)了ts格式相

          關(guān)的接口

          │ ├── srs_kernel_utility.cpp

          │ └── srs_kernel_utility.hpp 工具函數(shù),比如bool srs_string_ends_with(std::string str,

          std::string flag)

          ├── libs

          │ ├── srs_lib_bandwidth.cpp

          │ ├── srs_lib_bandwidth.hpp SrsBandwidthClient srs-librtmp 客戶端帶寬統(tǒng)計

          │ ├── srs_librtmp.cpp

          │ ├── srs_librtmp.hpp srs提供的客戶端rtmp庫

          │ ├── srs_lib_simple_socket.cpp

          │ └── srs_lib_simple_socket.hpp SimpleSocketStream rtmp客戶端的socket封裝10

          ├── main

          │ ├── srs_main_ingest_hls.cpp 拉取hls發(fā)布到rtmp流媒體服務(wù)器

          │ ├── srs_main_mp4_parser.cpp MP4 box解析

          │ └── srs_main_server.cpp srs流媒體服務(wù)器主入口

          ├── protocol 流媒體協(xié)議相關(guān)的協(xié)議都在這里

          │ ├── srs_http_stack.cpp

          │ ├── srs_http_stack.hpp HTTP協(xié)議

          │ ├── srs_protocol_amf0.cpp

          │ ├── srs_protocol_amf0.hpp Amf0解析

          │ ├── srs_protocol_format.cpp

          │ ├── srs_protocol_format.hpp SrsRtmpFormat繼承了SrsFormat, 代表RTMP格式

          │ ├── srs_protocol_io.cpp

          │ ├── srs_protocol_io.hpp 協(xié)議數(shù)據(jù)讀取的IO封裝接口,比如ISrsProtocolReadWriter

          │ ├── srs_protocol_json.cpp

          │ ├── srs_protocol_json.hpp json類

          │ ├── srs_protocol_kbps.cpp

          │ ├── srs_protocol_kbps.hpp 比特率統(tǒng)計相關(guān)

          │ ├── srs_protocol_stream.cpp

          │ ├── srs_protocol_stream.hpp 流讀取,從ISrsReader讀取數(shù)據(jù)到buffer里面

          │ ├── srs_protocol_utility.cpp

          │ ├── srs_protocol_utility.hpp 協(xié)議工具函數(shù)

          │ ├── srs_raw_avc.cpp

          │ ├── srs_raw_avc.hpp SrsRawH264Stream H264裸流解析,SrsRawAacStream AAC

          裸流解析

          │ ├── srs_rtmp_handshake.cpp

          │ ├── srs_rtmp_handshake.hpp RTMP握手,包括SrsSimpleHandshake和

          SrsComplexHandshake

          │ ├── srs_rtmp_msg_array.cpp

          │ ├── srs_rtmp_msg_array.hpp SrsMessageArray消息數(shù)組

          │ ├── srs_rtmp_stack.cpp

          │ ├── srs_rtmp_stack.hpp RTMP協(xié)議棧

          │ ├── srs_rtsp_stack.cpp

          │ └── srs_rtsp_stack.hpp RTSP協(xié)議棧

          ├── service

          │ ├── srs_service_conn.cpp

          │ ├── srs_service_conn.hpp ISrsConnection HTTP/RTMP/RTSP等對象的連接接口;

          IConnectionManager管理連接接口

          │ ├── srs_service_http_client.cpp

          │ ├── srs_service_http_client.hpp SrsHttpClient HTTP客戶端

          │ ├── srs_service_http_conn.cpp11

          │ ├── srs_service_http_conn.hpp HTTP連接 SrsHttpParser,SrsHttpMessage,

          SrsHttpResponseWriter,SrsHttpResponseReader

          │ ├── srs_service_log.cpp

          │ ├── srs_service_log.hpp SrsConsoleLog日志相關(guān)

          │ ├── srs_service_rtmp_conn.cpp

          │ ├── srs_service_rtmp_conn.hpp SrsBasicRtmpClient RTMP客戶端類

          │ ├── srs_service_st.cpp

          │ ├── srs_service_st.hpp 對st-thread協(xié)程的封裝

          │ ├── srs_service_utility.cpp

          │ └── srs_service_utility.hpp service組件的工具類

          └── utest

          ├── srs_utest_amf0.cpp

          ├── srs_utest_amf0.hpp

          ├── srs_utest_app.cpp

          ├── srs_utest_app.hpp

          ├── srs_utest_avc.cpp

          ├── srs_utest_avc.hpp

          ├── srs_utest_config.cpp

          ├── srs_utest_config.hpp

          ........... 還有其他utest文件,這里忽略

          8 directories, 203 files

          ava 監(jiān)控直播流rtsp協(xié)議轉(zhuǎn)rtmp、hls、httpflv協(xié)議返回瀏覽器

          目錄

          • 一:了解音視頻流協(xié)議:
          • 二:方案一 rtsp 轉(zhuǎn)rtmp1、下載nginx + nginx-rtmp-module3、cmd 到nginx根目錄啟動nginx8、查攝像頭的rtsp協(xié)議格式10、測試rtmp是否轉(zhuǎn)換成功12、為什么放棄了用rtmp
          • 四:方案三rtsp 轉(zhuǎn)httpflv(采用)1、安裝nginx-flv-module4.1 采用java代碼去執(zhí)行ffmepg命令6、前端使用flv.js播放:

          需求背景:

          在做之前的項(xiàng)目的時候有一個對接攝像頭實(shí)時播放的需求,由于我們攝像頭的購買量不是很多,海康威視不給我們提供流媒體云服務(wù)器,所以需要我們自己去 一個去滿足我們能在瀏覽器看到監(jiān)控畫面。項(xiàng)目源代碼在以前公司沒有拷貝就不能復(fù)習(xí),最近又在準(zhǔn)備面試,所以寫了這個博客來復(fù)盤和擴(kuò)展一下,由于我現(xiàn)在沒有Liunx,我就用Windows來演示,生產(chǎn)環(huán)境還是要使用Liunx,下面這些操作在Liunx也是一樣的流程,大家自行百度。

          一:了解音視頻流協(xié)議:

          媒體流協(xié)議對比

          協(xié)議

          HttpFlv

          RTMP

          HLS

          Dash

          全稱

          FLASH VIDEO over HTTP

          Real Time Message Protocol

          HTTP Living Streaming


          傳輸方式

          HTTP長連接

          TCP長連接

          HTTP短連接

          HTTP短連接

          視頻封裝格式

          FLV

          FLV TAG

          TS文件

          Mp4

          3gp

          webm

          原理

          同 RTMP ,使用HTTP協(xié)議(80端口)

          每個時刻的數(shù)據(jù)收到后立刻轉(zhuǎn)發(fā)

          集合一段時間的數(shù)據(jù),生成TS切片文件(三片),并更新m3u8索引


          延時

          1~3秒

          1~3秒

          5~20秒(依切片情況)

          數(shù)據(jù)分段

          連續(xù)流

          連續(xù)流

          切片文件

          切片文件

          Html5播放

          可通過HTML5解封包播放

          (flv.js)

          不支持

          可通過HTML5解封包播放

          (hls.js)

          如果dash文件列表是MP4,

          webm文件,可直接播放

          其它

          需要Flash技術(shù)支持,不支持多音頻流、多視頻流,不便于seek(即拖進(jìn)度條)

          跨平臺支持較差,需要Flash技術(shù)支持

          播放時需要多次請求,對于網(wǎng)絡(luò)質(zhì)量要求高


          二:方案一 rtsp 轉(zhuǎn)rtmp

          1、下載nginx + nginx-rtmp-module

          nginx:下載地址: http://nginx-win.ecsds.eu/download/

          nginx-rtmp-module:nginx 的擴(kuò)展,安裝后支持rtmp協(xié)議,下載地址: https://github.com/arut/nginx-rtmp-module

          解壓nginx-rtmp-module到nginx根目錄下,并修改其文件夾名為nginx-rtmp-module(原名為nginx-rtmp-module-master)

          2、nginx配置文件

          到nginx根目錄下的conf目錄下復(fù)制一份nginx-win.conf 重命名 nginx-win-rtmp.conf

          nginx-win-rtmp.conf:

          #user  nobody;
          # multiple workers works !
          worker_processes  2;
          
          #error_log  logs/error.log;
          #error_log  logs/error.log  notice;
          #error_log  logs/error.log  info;
          
          #pid        logs/nginx.pid;
          
          events {
              worker_connections  8192;
              # max value 32768, nginx recycling connections+registry optimization = 
              #   this.value * 20 = max concurrent connections currently tested with one worker
              #   C1000K should be possible depending there is enough ram/cpu power
              # multi_accept on;
          }
          
          rtmp {
              server {
                  listen 1935;
                  chunk_size 4000;
          		
                  application live {
                       live on;
                       # 播放時進(jìn)行回調(diào),如果HttpRespone statusCode不等于200會斷開
          			 # on_play http://localhost:8081/auth;
                  }
          		
          		application hls {
          		     live on; 
          		     # 開啟hls切片
                       hls on;
                       # m3u8地址
          			 hls_path html/hls;
          			 # 一個切片多少秒
          			 hls_fragment 8s;
          			 # on_play http://localhost:8081/auth;
          			 # on_publish http://localhost:8081/auth;
          			 # on_done http://localhost:8081/auth;
                  }
              }
          }
          
          http {
              #include      /nginx/conf/naxsi_core.rules;
              include       mime.types;
              default_type  application/octet-stream;
          
              #log_format  main  '$remote_addr:$remote_port - $remote_user [$time_local] "$request" '
              #                  '$status $body_bytes_sent "$http_referer" '
              #                  '"$http_user_agent" "$http_x_forwarded_for"';
          
              #access_log  logs/access.log  main;
          
          #     # loadbalancing PHP
          #     upstream myLoadBalancer {
          #         server 127.0.0.1:9001 weight=1 fail_timeout=5;
          #         server 127.0.0.1:9002 weight=1 fail_timeout=5;
          #         server 127.0.0.1:9003 weight=1 fail_timeout=5;
          #         server 127.0.0.1:9004 weight=1 fail_timeout=5;
          #         server 127.0.0.1:9005 weight=1 fail_timeout=5;
          #         server 127.0.0.1:9006 weight=1 fail_timeout=5;
          #         server 127.0.0.1:9007 weight=1 fail_timeout=5;
          #         server 127.0.0.1:9008 weight=1 fail_timeout=5;
          #         server 127.0.0.1:9009 weight=1 fail_timeout=5;
          #         server 127.0.0.1:9010 weight=1 fail_timeout=5;
          #         least_conn;
          #     }
          
              sendfile        off;
              #tcp_nopush     on;
          
              server_names_hash_bucket_size 128;
          
          ## Start: Timeouts ##
              client_body_timeout   10;
              client_header_timeout 10;
              keepalive_timeout     30;
              send_timeout          10;
              keepalive_requests    10;
          ## End: Timeouts ##
          
              #gzip  on;
          
              server {
                  listen       5080;
                  server_name  localhost;
          
          
                  location /stat {
                      rtmp_stat all;
                      rtmp_stat_stylesheet stat.xsl;
                  }
                  location /stat.xsl {
                      root nginx-rtmp-module/;
                  }
                  location /control {
                      rtmp_control all;
                  }
          		
          		location /hls {
                      # Serve HLS fragments
                      types {
                          application/vnd.apple.mpegurl m3u8;
                          video/mp2t ts;
                      }
                      expires -1;
                      add_header Access-Control-Allow-Origin *;
                  }
          
                  #charset koi8-r;
                  #access_log  logs/host.access.log  main;
          
                  ## Caching Static Files, put before first location
                  #location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
                  #    expires 14d;
                  #    add_header Vary Accept-Encoding;
                  #}
          
          # For Naxsi remove the single # line for learn mode, or the ## lines for full WAF mode
                  location / {
                      #include    /nginx/conf/mysite.rules; # see also http block naxsi include line
                      ##SecRulesEnabled;
                   ##DeniedUrl "/RequestDenied";
                   ##CheckRule "$SQL >= 8" BLOCK;
                   ##CheckRule "$RFI >= 8" BLOCK;
                   ##CheckRule "$TRAVERSAL >= 4" BLOCK;
                   ##CheckRule "$XSS >= 8" BLOCK;
                      root   html;
                      index  index.html index.htm;
                  }
          
          # For Naxsi remove the ## lines for full WAF mode, redirect location block used by naxsi
                  ##location /RequestDenied {
                  ##    return 412;
                  ##}
          
          ## Lua examples !
          #         location /robots.txt {
          #           rewrite_by_lua '
          #             if ngx.var.http_host ~= "localhost" then
          #               return ngx.exec("/robots_disallow.txt");
          #             end
          #           ';
          #         }
          
                  #error_page  404              /404.html;
          
                  # redirect server error pages to the static page /50x.html
                  #
                  error_page   500 502 503 504  /50x.html;
                  location = /50x.html {
                      root   html;
                  }
          
                  # proxy the PHP scripts to Apache listening on 127.0.0.1:80
                  #
                  #location ~ \.php$ {
                  #    proxy_pass   http://127.0.0.1;
                  #}
          
                  # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
                  #
                  #location ~ \.php$ {
                  #    root           html;
                  #    fastcgi_pass   127.0.0.1:9000; # single backend process
                  #    fastcgi_pass   myLoadBalancer; # or multiple, see example above
                  #    fastcgi_index  index.php;
                  #    fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
                  #    include        fastcgi_params;
                  #}
          
                  # deny access to .htaccess files, if Apache's document root
                  # concurs with nginx's one
                  #
                  #location ~ /\.ht {
                  #    deny  all;
                  #}
              }
          
              # another virtual host using mix of IP-, name-, and port-based configuration
              #
              #server {
              #    listen       8000;
              #    listen       somename:8080;
              #    server_name  somename  alias  another.alias;
          
              #    location / {
              #        root   html;
              #        index  index.html index.htm;
              #    }
              #}
          
              # HTTPS server
              #
              #server {
              #    listen       443 ssl spdy;
              #    server_name  localhost;
          
              #    ssl                  on;
              #    ssl_certificate      cert.pem;
              #    ssl_certificate_key  cert.key;
              #    ssl_session_timeout  5m;
              #    ssl_prefer_server_ciphers On;
              #    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
              #    ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:ECDH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!eNULL:!MD5:!DSS:!EXP:!ADH:!LOW:!MEDIUM;
          
              #    location / {
              #        root   html;
              #        index  index.html index.htm;
              #    }
              #}
          
          }

          3、cmd 到nginx根目錄啟動nginx

          nginx.exe -c conf\nginx-win-rtmp.conf

          測試:瀏覽器輸入 http://localhost:5080/stat,看到

          代表安裝成功

          4、下載ffmpeg安裝

          ffmpeg:一個處理音視頻強(qiáng)大的庫,我們需要用它來轉(zhuǎn)協(xié)議,下載地址: https://www.gyan.dev/ffmpeg/builds/ ,這里可以下載essential和full版本,essential就是簡版,只包含ffmpeg.exe、ffplay.exe、

          ffprobe.exe, 而full版本就包含了動態(tài)庫和相關(guān)頭文件,方便我們在開發(fā)中調(diào)用。

          5、配置ffmpeg環(huán)境變量

          將ffmpeg解壓后里面的bin路徑復(fù)制到Path里面去

          6、測試ffmpeg

          cmd ffmpeg -version 命令看到代表成功

          7、下載VLC播放器

          下載地址: https://www.videolan.org/vlc/

          8、查攝像頭的rtsp協(xié)議格式

          我這里截圖是海康威視的

          現(xiàn)在沒有測試的流,我找了個點(diǎn)播的rtsp

          rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mp4,用這個代替是一樣的

          9、執(zhí)行ffmpeg命令

          ffmpeg強(qiáng)大,命令也是復(fù)雜,我們cmd 執(zhí)行

          ffmpeg -re -rtsp_transport tcp -stimeout 20000000 -i "rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mp4" -buffer_size 1024000 -max_delay 500000 -codec:v libx264 -r 25 -rtbufsize 10M -s 1280x720 -map:v 0 -an -f flv rtmp://127.0.0.1:1935/live/test

          rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mp4,是輸入源頭

          rtmp://127.0.0.1:1935/live/test 是輸出地址

          如果沒有報錯的話,到現(xiàn)在rtsp就已經(jīng)轉(zhuǎn)換好了

          ffmpeg命令學(xué)習(xí): https://www.jianshu.com/p/df3216a52e59 、 https://blog.csdn.net/fuhanghang/article/details/123565920

          10、測試rtmp是否轉(zhuǎn)換成功

          我們打開VLC,媒體->打開網(wǎng)絡(luò)串流->輸入 rtmp://127.0.0.1:1935/live/test -> 播放

          11、測試是否成功

          等待幾秒鐘看到有視頻播放就是成功了

          12、為什么放棄了用rtmp

          rtmp的優(yōu)點(diǎn)是延遲低,效率高,但是在瀏覽器需要安裝flash才能放,也就老版本的瀏覽器在用,rtmp可能會在別的地方支持,所以還是把他方式方法貼出來了。

          三:方案二 rtsp轉(zhuǎn)hls

          1、nginx配置:

          在前面已經(jīng)貼出來了,其中這幾個是針對hls的

          2、執(zhí)行ffmepg命令

          ffmpeg -i "rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mp4" -vcodec libx264 -acodec aac -f flv rtmp://127.0.0.1:1935/hls/test

          3、查看nginx根目錄 -> hls -> test.m3u8 是否生成

          生成了代表一切正常

          4、m3u8在網(wǎng)頁上播放

          <!DOCTYPE html>
          <html lang="zh-CN">
          <head>
              <meta charset="UTF-8">
              <title>前端播放m3u8格式視頻</title>
              <!--https://www.bootcdn.cn/video.js/-->
              <link href="https://cdn.bootcss.com/video.js/7.6.5/alt/video-js-cdn.min.css" rel="stylesheet">
              <script src="https://cdn.bootcss.com/video.js/6.6.2/video.js"></script>
              <!--https://www.bootcdn.cn/videojs-contrib-hls/-->
              <script src="https://cdn.bootcss.com/videojs-contrib-hls/5.15.0/videojs-contrib-hls.min.js"></script>
          </head>
          <body>
              <video id="myVideo" class="video-js vjs-default-skin vjs-big-play-centered" controls preload="auto" width="1080" height="708" data-setup='{}'>    
                  <source id="source" src="http://127.0.0.1:5080/hls/test.m3u8"  type="application/x-mpegURL">
              </video>
          </body>
          <script>    
              // videojs 簡單使用  
              var myVideo = videojs('myVideo',{
                  bigPlayButton : true, 
                  textTrackDisplay : false, 
                  posterImage: false,
                  errorDisplay : false,
              })
              myVideo.play() // 視頻播放
              myVideo.pause() // 視頻暫停
          </script>
          </html>

          source標(biāo)簽的src屬性: http://你的nginx ip:nginx http端口/hls/test.m3u8

          rtsp轉(zhuǎn)HLS成功!

          5、認(rèn)識一下m3u8格式

          m3u8文件里面存儲了一個索引,以文本格式打開是這樣的

          #EXTM3U
          #EXT-X-VERSION:3
          #EXT-X-MEDIA-SEQUENCE:56
          #EXT-X-TARGETDURATION:13
          #EXTINF:10.381,
          test-56.ts
          #EXTINF:10.422,
          test-57.ts
          #EXTINF:13.453,
          test-58.ts

          m3u8文件它不是視頻源,源頭是ts后綴文件

          6、為什么放棄了用HLS

          轉(zhuǎn)HLS協(xié)議及網(wǎng)頁加載過程:

          ffmepg收到rtsp的流時候,會等一個切片的時間,一個切片時間到了,切片ts會放到服務(wù)器中,同時m3u8文件中加一個索引,對應(yīng)著新進(jìn)入的切片。網(wǎng)頁在加載m3u8的時候,就是讀取m3u8中的的索引去加載ts文件,所以在不斷的請求ts,對ts進(jìn)行解析,不斷的和TCP握手,這就是為什么HLS延遲高和對網(wǎng)速的要求高的原因,我們監(jiān)控肯定是要延遲低的,HLS兼容性好,適合點(diǎn)播。

          四:方案三rtsp 轉(zhuǎn)httpflv(采用)

          1、安裝nginx-flv-module

          這個插件需要編譯,教程: https://blog.csdn.net/KayChanGEEK/article/details/105095844

          我這里已經(jīng)編譯好了,直接下載啟動:

          https://gitee.com/isyuesen/nginx-flv-file

          2、nginx配置

          看我git里面的https://gitee.com/isyuesen/nginx-flv-file/blob/master/conf/nginx.conf,和默認(rèn)的config差別主要是添加了這幾個

          rtmp {  
              server {  
                  listen 1935;
                  # 流復(fù)用的最大塊大小
                  chunk_size 4000;  
                  application liveapp { 
                      live on;
                      # 推流開始
          			on_publish http://localhost:8081/auth;
          			# 推流關(guān)閉
          			on_publish_done http://localhost:8081/auth;
          			# 客戶端開始播放
          			on_play http://localhost:8081/auth;
          			# 客戶端結(jié)束播放
          			on_play_done http://localhost:8081/auth;
                  }  
              }  
          }
          location /live {
              flv_live on;
              chunked_transfer_encoding on;
              add_header 'Access-Control-Allow-Credentials' 'true'; #add additional HTTP header
              add_header 'Access-Control-Allow-Origin' '*'; #add additional HTTP header
              add_header Access-Control-Allow-Headers X-Requested-With;
              add_header Access-Control-Allow-Methods GET,POST,OPTIONS;
              add_header 'Cache-Control' 'no-cache';
          }

          3、做java權(quán)限認(rèn)證

          nginx rtmp配置中有配置on_publish鉤子接口 http://localhost:8081/auth,這個回調(diào)HttpResponse stausCode如果不等于200會拒絕I/O,更多回調(diào)鉤子看: https://github.com/arut/nginx-rtmp-module/wiki/Directives#on_connect

          @PostMapping("/auth")
              public void getVideo(String token, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
                  if (token.equals("tokenValue")) {
                      httpServletResponse.setStatus(200);
                  } else {
                      // 拒絕服務(wù)
                      httpServletResponse.setStatus(500);
                  }
              }

          4、執(zhí)行ffmepg命令:

          ffmpeg -re  -rtsp_transport tcp -i "rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mp4" -f flv -vcodec h264 -vprofile baseline -acodec aac -ar 44100 -strict -2 -ac 1 -f flv -s 640*360 -q 10 "rtmp://127.0.0.1:1935/liveapp/test"

          4.1 采用java代碼去執(zhí)行ffmepg命令

          依賴 javaCV

          <dependency>
              <groupId>org.bytedeco</groupId>
              <artifactId>javacv-platform</artifactId>
              <version>1.5.2</version>
          </dependency>
          public class App {
              public static void main( String[] args ) throws IOException, InterruptedException {
                  String name = "test";
                  // rtsp地址
                  String rtspDir = "rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mp4";
                  // rtmp地址
                  String rtmpDir = "rtmp://192.168.0.140:1935/liveapp/" + name + "?token=tokenValue";
          
                  String ffmpeg = Loader.load(org.bytedeco.ffmpeg.ffmpeg.class);
                  ProcessBuilder pb = new ProcessBuilder(ffmpeg,
                          "-re",
                          "-rtsp_transport",
                          "tcp",
                          "-i",
                          rtspDir,
                          "-f",
                          "flv",
                          "-vcodec",
                          "h264",
                          "-vprofile",
                          "baseline",
                          "-acodec",
                          "aac",
                          "-ar",
                          "44100",
                          "-strict",
                          "-2",
                          "-ac",
                          "1",
                          "-f",
                          "flv",
                          "-s",
                          "640*360",
                          "-q",
                          "10",
                          rtmpDir
                  );
                  pb.inheritIO().start().waitFor();
              }
          }

          5、測試http-flv鏈接

          如果你跟著我做的,那鏈接就是 http://127.0.0.1:18080/live?port=1935&app=liveapp&stream=test&token=tokenValue,在VLC播放器中點(diǎn)擊媒體 -> 打開網(wǎng)絡(luò)串流 -> 輸入http://127.0.0.1:18080/live?port=1935&app=liveapp&stream=test&token=tokenValue -> 播放

          有視頻證明你離成功就差最后一步

          6、前端使用flv.js播放:

          <!doctype html>
          <html lang="en">
          <head>
            <meta charset="UTF-8">
            <meta name="viewport"
                  content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
            <meta http-equiv="X-UA-Compatible" content="ie=edge">
            <title>播放http-flv</title>
          </head>
          <body>
          <video id="videoElement"></video>
          <script src="https://cdn.bootcdn.net/ajax/libs/flv.js/1.6.2/flv.min.js"></script>
          <script>
            if (flvjs.isSupported()) {
                const videoElement = document.getElementById('videoElement');
                const flvPlayer = flvjs.createPlayer({
                  type: 'flv',
                  url: 'http://127.0.0.1:18080/live?port=1935&app=liveapp&stream=test&token=tokenValue'
                });
                flvPlayer.attachMediaElement(videoElement);
                flvPlayer.load();
                flvPlayer.play();
          	}
          </script>
          </body>
          </html>

          7、大功告成


          主站蜘蛛池模板: 亚洲AV美女一区二区三区| 亚洲一区视频在线播放| 日本一区二区在线免费观看| 久久青草国产精品一区| 日本高清天码一区在线播放| 久久精品国产AV一区二区三区| 国产99精品一区二区三区免费 | 国产女人乱人伦精品一区二区 | 亚洲国产精品乱码一区二区| 国产一区二区在线观看视频| 无码人妻aⅴ一区二区三区有奶水| 国产av一区二区三区日韩| 精品一区二区无码AV| 国产精品一区二区av不卡| 一区二区三区在线播放| 国产午夜一区二区在线观看| 日韩在线视频一区二区三区| 国产香蕉一区二区三区在线视频| 91精品一区二区三区久久久久 | 亚洲一区免费观看| 亚洲图片一区二区| 亚洲一区无码中文字幕乱码| 人妻天天爽夜夜爽一区二区| 无码人妻精品一区二区三区在线 | 波多野结衣一区二区三区高清av | 国产在线精品一区二区不卡| 亚洲国产一区明星换脸| 国产午夜精品一区二区三区小说 | 人妻AV中文字幕一区二区三区 | 成人丝袜激情一区二区| 亚洲日韩中文字幕一区| 无码人妻一区二区三区av| 无码中文字幕一区二区三区| 日韩精品中文字幕视频一区| 视频精品一区二区三区| 精品国产毛片一区二区无码| 国产一区二区三区不卡AV| 久久久精品人妻一区二区三区 | 人妻体内射精一区二区三区| 亚洲福利视频一区二区三区| 人妻少妇精品视频三区二区一区|