華為海康大華攝像頭編譯RTSP轉RTMP和HTTPFLV
- 專案需求要看攝像頭實時畫面谷歌瀏覽器不支持RTSP流直接展示
- 方案一 通過Java+nginx+rtsp轉rtmp流
- 方案二 通過Java+ Nginx-http-flv-module + FFmpeg + Flv.js 實作rtsp轉flv在vue專案中 (采用)
專案需求要看攝像頭實時畫面谷歌瀏覽器不支持RTSP流直接展示
因為開發一般用的都是谷歌瀏覽器但是谷歌瀏覽器不支持rtsp流直接轉化視頻,就靠著網上的博文一直嘗試 最終總結了一套流程 自學
方案一 通過Java+nginx+rtsp轉rtmp流
直接進入主題,第一次嘗試通過Javacv + nginx-moudle-temp (下邊放地址) 直接轉rtmp流
原文地址 原文地址
因為nginx+rtmpMoudles需要編譯 我把地址放到云上下載解壓 雙擊nginx.exe就能使用 配置無需修改
所需依賴
<!-- javacv1.5.1 -->
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>javacv</artifactId>
<version>1.5.1</version>
</dependency>
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>ffmpeg-platform</artifactId>
<version>4.1.3-1.5.1</version>
</dependency>
Java代碼如下:
/**
*
* @param rtmpPath 推流地址 rtmp://127.0.0.1:1935/live/(這個地方寫不寫都行自己琢磨吧)
* rtspPath rtsp流地址
* audioRecord 是否錄制 0= 不錄制 1=錄制
* saveVideo 是否保存視頻
* @return
*/
public static void test(String rtmpPath,String rtspPath,int audioRecord,boolean saveVideo ) throws Exception {
//FrameGrabber grabber = FrameGrabber.createDefault(0); // 本機攝像頭 默認
// 使用rtsp的時候需要使用 FFmpegFrameGrabber,不能再用 FrameGrabber
int width = 640,height = 480;
FFmpegFrameGrabber grabber = FFmpegFrameGrabber.createDefault(rtspPath);
grabber.setOption("rtsp_transport", "tcp"); // 使用tcp的方式,不然會丟包很嚴重
// 一直報錯的原因!!!就是因為是 2560 * 1440的太大了,,
grabber.setImageWidth(width);
grabber.setImageHeight(height);
System.out.println("grabber start");
grabber.start();
//FrameRecorder recorder = FrameRecorder.createDefault(rtmpPath, 640,480,0);
// 流媒體輸出地址,解析度(長,高),是否錄制音頻(0:不錄制/1:錄制)
FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(rtmpPath, width, height, audioRecord);
recorder.setInterleaved(true);
recorder.setVideoOption("crf","28");
recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264); // 28
recorder.setFormat("flv"); // rtmp的型別
recorder.setFrameRate(25);
recorder.setPixelFormat(0); // yuv420p
System.out.println("recorder start");
recorder.start();
//
OpenCVFrameConverter.ToIplImage conveter = new OpenCVFrameConverter.ToIplImage();
System.out.println("all start!!");
int count = 0;
while(!exit){
count++;
Frame frame = grabber.grabImage();
if(frame == null){
continue;
}
if(count % 100 == 0){
System.out.println("count="+count);
}
recorder.record(frame);
}
grabber.stop();
grabber.release();
recorder.stop();
recorder.release();
}
因為這個方案轉出來的流是rtmp 這個流需要配合flash使用 在2020年年底
谷歌就停止了對flash的支持所以這個方案被pass
代碼親測可用 因為不是通過中間件轉流是通過 Java封裝的FFmpeg轉的所以延遲測驗在19秒左右
方案二 通過Java+ Nginx-http-flv-module + FFmpeg + Flv.js 實作rtsp轉flv在vue專案中 (采用)
因為在第一個方案中rtmp流在谷歌瀏覽器中無法播放 所以改變方案
- 部署所需的軟體 FFmpeg在官網上下載配置下環境變數就行了如下圖就是配置成功

- 部署 Nginx-http-flv-module這是原始碼地址 自己編譯一下就好了 啟動之后配置下組態檔
以我的為例:
這個在http server下邊 這個是flv的配置 獲取到rtmp之后轉為flv
location /flv {
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';
}
location /hls {
add_header Access-Control-Allow-Origin *;
types{
application/vnd.apple.mpegurl m3u8;
video/mp2t ts;
}
alias /test;
expires -1;
}
location /stat {
rtmp_stat all;
rtmp_stat_stylesheet stat.xsl;
}
location /stat.xsl {
root html/nginx-http-flv-module/;
}
location /control {
rtmp_control all;
}
location /rtmp-publisher {
root html/nginx-http-flv-module/test;
}
這個在外邊 因為是通過rtsp轉rtmp
rtmp {
server {
listen 1935;
chunk_size 4000;
application hls {
live on;
hls on;
hls_path /test;
hls_fragment 1s;
}
}
}
3.配置完成之后跟第一個方案一樣 測驗安裝好沒有 雙擊nginx.exe 看下后臺行程 如果有nginx 呢就是正常啟動 如果沒有看下log里邊的報錯資訊 我的沒有出問題
4.通過Java拼接FFmpeg命令 將rtsp通過FFmpeg轉為rtmp 推流到nginx ,FFmpeg命令自行百度
代碼:
/**
* 推送到nginx的流地址按照自己配置的資訊進行拼接不是固定的
* @param nginxRtmpUrl 推流地址 rtmp://127.0.0.1:1935/hls/rtmpStream
* rtspUrl rtsp流地址
* @return
*/
public static Integer pushVideoAsRTSP(String rtspUrl, String nginxRtmpUrl) {
int flag = -1;
try {
String command = "ffmpeg ";
command += " -re -rtsp_transport tcp -i " + rtspUrl;
command += " -f flv -vcodec libx264 -vprofile baseline -acodec aac -ar 44100 -strict -2 -ac 1 -f flv -s 800x600 -q 10 " + nginxRtmpUrl;
System.out.println("ffmpeg推流命令:" + command);
Process process = Runtime.getRuntime().exec(command);
BufferedReader br = new BufferedReader(new InputStreamReader(process.getErrorStream()));
String line = "";
while ((line = br.readLine()) != null) {
System.out.println("視頻推流資訊[" + line + "]");
}
flag = process.waitFor();
} catch (Exception e) {
e.printStackTrace();
}
return flag;
}
5.運行這個方法之后會出現可以通過vlc進行測驗rtmp流地址 如果rtmp能顯示畫面 往下進行測驗自行拼接flv地址 地址按照上邊nginx組態檔進行配置
http://127.0.0.1:18080/flv?app=hls&stream=rtmpStream
6.web端通過vue實作
安裝flv.js
npm install --save flv.js
全域參考的話放到main.js
我沒有全域參考直接上vue全部代碼
<video id="videoElement" controls autoplay muted width="800px" height="400px"></video>
import flvjs from "flv.js"
export default {
data() {
return {
flvPlayer: null
}
},
mounted() {
if (flvjs.isSupported()) {
var videoElement = document.getElementById('videoElement');
this.flvPlayer = flvjs.createPlayer({
type: 'flv',
isLive: true,
hasAudio: false,
url: 'http://127.0.0.1:18080/flv?app=hls&stream=rtmpStream'
});
this.flvPlayer.attachMediaElement(videoElement);
this.flvPlayer.load();
this.flvPlayer.play();
}
}
}
flv測驗用的demo
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>播放頁面</title>
</head>
<body>
<script src="https://cdn.bootcdn.net/ajax/libs/flv.js/1.5.0/flv.min.js"></script>
<video style="height: 400px;width: 600px;" id="videoElement" muted autoplay controls></video>
<script>
var flvPlayer = null;
if (flvjs.isSupported()) {
var videoElement = document.getElementById('videoElement');
flvPlayer = flvjs.createPlayer({
type: 'flv',
// 8080 對應Nginx監聽的埠
// rtmpLive 對應Nginx的路徑
url: 'http://127.0.0.1:18080/flv?app=hls&stream=rtmpStream'
});
flvPlayer.attachMediaElement(videoElement);
flvPlayer.load();
}
</script>
</body>
</html>
延遲重繪之后七秒 但是web端不穩定 延遲會越來越大

推流時間一小時二十分鐘 流還是很穩定 vlc 延遲一直穩定在十秒左右


上邊有些代碼是從網上找到 我也忘了出處在哪 侵刪
這些方法延遲比較高 如果對延遲有比較嚴格的 我覺得可以研究下vlc在軟硬體上邊下手 可能會比較好點
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/349759.html
標籤:其他
