赞
踩
工作需要研究下市面上显示实时视频方案。这里介绍下RTMP协议。
需求获取USB摄像头,手机谁摄像头。显示到web网页上。
这个使用opencvSharp来采集:
nuget:
- var task = Task.Run(() =>
- {
-
- var capture = new VideoCapture(0);
- VideoCaptureProperties captureProperties = new VideoCaptureProperties();
-
- capture.Fps = 30;
-
- //苹果测试流
- //var capture = new VideoCapture("http://devimages.apple.com.edgekey.net/streaming/examples/bipbop_4x3/gear2/prog_index.m3u8", VideoCaptureAPIs.FFMPEG);
- if (!capture.IsOpened())
- {
- ShowContent("Failed to open capture");
- return;
- }
-
- //capture.Set(captureProperties, 80);
-
- var frame = new Mat();
- var process = new Process();
- while (true)
- {
- capture.Read(frame);
- if (frame.Size().Width > 0 && frame.Size().Height > 0)
- {
- HersheyFonts fontFace = new HersheyFonts();
- frame.PutText(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), new OpenCvSharp.Point(10, 30), fontFace, 1.0, Scalar.Red);
- //var buffer = frame.ToBytes();
- //byte[] bytes = frame.ToBytes(".jpg");
- #region 压缩尺寸变小
- //Cv2.Resize(frame, frame, new OpenCvSharp.Size(frame.Width / 2, frame.Height / 2));
- byte[] bytes = CompressImEncode(frame); //CompressImEncodeNew(frame); //
- //预览压缩
- frame = Mat.FromImageData(bytes);
-
- #endregion
- MatToBitmapShow(frame);
-
- MemoryStream memory = new MemoryStream();
- memory.Write(bytes, 0, bytes.Length);
- memory.Write(_delimiter, 0, _delimiter.Length);
- SendTCP(memory.ToArray());
- //Cv2.ImShow("Video", frame);
- //Cv2.WaitKey(1);
- // 延时一段时间
- Cv2.WaitKey(1);
- }
- }
- });
这里使用 nginx-rtmp-http-flv
- worker_processes 1;
-
- events {
- worker_connections 1024;
- }
-
- rtmp {
- server {
- listen 1935;
-
- application live {
- live on;
- ##打开 GOP 缓存,减少首屏等待时间
- gop_cache on ; #打开GOP缓存,减少首屏等待时间
- record_max_size 1K; #设置录制文件的最大值。
-
-
- }
- }
- }
-
- #推流地址:rtmp://192.168.1.194:1935/live/video1
- #FLV 播放地址:http://127.0.0.1:8088/flv?port=1935&app=live&stream=video1
-
- http {
- include mime.types;
- default_type application/octet-stream;
-
- sendfile on;
-
- keepalive_timeout 65;
-
- server {
- listen 8088;
- server_name localhost;
-
- location / {
- add_header 'Access-Control-Allow-Origin' '*';
- root html;
- index index.html index.htm;
- }
-
- location /live {
- flv_live on;
- }
-
- location /flv {
- add_header 'Access-Control-Allow-Origin' '*';
- flv_live on;
- chunked_transfer_encoding on;
- }
-
- error_page 500 502 503 504 /50x.html;
- location = /50x.html {
- root html;
- }
- }
- }
写推流到流媒体服务器:
- string rtmp1 = "rtmp://127.0.0.1:1935/live/video1";
- string rtmp2 = "rtmp://127.0.0.1/live/test110";
-
- task = Task.Run(() =>
- {
- // 初始化 FFmpeg 库
- var capture = new VideoCapture(0);
- //var capture = new VideoCapture("http://devimages.apple.com.edgekey.net/streaming/examples/bipbop_4x3/gear2/prog_index.m3u8", VideoCaptureAPIs.FFMPEG);
- if (!capture.IsOpened())
- {
- ShowContent("Failed to open capture");
- return;
- }
-
- var frame = new Mat();
- var process = new Process();
- process.StartInfo.FileName = "ffmpeg";
- //aac 音频 -r 25 帧率25 -acodec aac
- process.StartInfo.Arguments = "-re -i - -vcodec libx264 -f flv " + rtmp1;
- process.StartInfo.UseShellExecute = false;
- process.StartInfo.RedirectStandardInput = true;
- //下面这设置使其后台运行
- process.StartInfo.CreateNoWindow = true;
-
- process.Start();
-
- while (true)
- {
- capture.Read(frame);
- if (frame.Size().Width > 0 && frame.Size().Height > 0)
- {
- HersheyFonts fontFace = new HersheyFonts();
- frame.PutText(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), new OpenCvSharp.Point(10, 30), fontFace, 1.0, Scalar.Red);
- var buffer = frame.ToBytes();
-
- process.StandardInput.BaseStream.Write(buffer, 0, buffer.Length);
- MatToBitmapShow(frame);
- //Cv2.ImShow("Video", frame);
- //Cv2.WaitKey(1);
- }
- }
- process.WaitForExit();
- });
效果:
- <!DOCTYPE html><html><head>
- <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
- <title>flv.js demo</title>
- <style>
- .mainContainer { display: block; width: 1024px; margin-left: auto; margin-right: auto;
- } .urlInput { display: block; width: 100%; margin-left: auto; margin-right: auto; margin-top: 8px; margin-bottom: 8px;
- } .centeredVideo { display: block; width: 100%; height: 576px; margin-left: auto; margin-right: auto; margin-bottom: auto;
- } .controls { display: block; width: 100%; text-align: left; margin-left: auto; margin-right: auto;
- }
-
- </style>
- </head>
-
- <body>
-
- <h1>FLV </h1>
- <div class="mainContainer">
- <video id="videoElement" class="centeredVideo" controls autoplay width="1024" height="576">Your browser is too old which doesn't support HTML5 video.</video>
- </div>
- <br>
- <div class="controls">
- <!--<button onclick="flv_load()">加载</button>-->
- <button onclick="flv_start()">开始</button>
- <button onclick="flv_pause()">暂停</button>
- <button onclick="flv_destroy()">停止</button>
- <input style="width:100px" type="text" name="seekpoint" />
- <button onclick="flv_seekto()">跳转</button>
- </div>
- <script src="flv.min.js"></script>
- <script>
- var player = document.getElementById('videoElement');
- if (flvjs.isSupported()) {
- var flvPlayer = flvjs.createPlayer({
- type: 'flv',
- "isLive": true,//<====加个这个
- url: 'http://192.168.1.194:8088/flv?port=1935&app=live&stream=video1',//<==自行修改
-
- //url: 'http://127.0.0.1:8080/live/test110.flv',
- });
- flvPlayer.attachMediaElement(videoElement);
- flvPlayer.load(); //加载
- flv_start();
- }
- function flv_start() {
- player.play();
- }
- function flv_pause() {
- player.pause();
- }
- function flv_destroy() {
- player.pause();
- player.unload();
- player.detachMediaElement();
- player.destroy();
- player = null;
- }
- function flv_seekto() {
- player.currentTime = parseFloat(document.getElementsByName('seekpoint')[0].value);
- }
-
- $(function(){
- flv_start();
- });
-
- // setInterval(() => {
- // if (this.player.buffered.length) {
- // let end = this.player.buffered.end(0);//获取当前buffered值
- // let diff = end - this.player.currentTime;//获取buffered与currentTime的差值
- // if (diff >= 0.5) {//如果差值大于等于0.5 手动跳帧 这里可根据自身需求来定
- // this.player.currentTime = this.player.buffered.end(0);//手动跳帧
- // }
- // }
- // }, 2000); //2000毫秒执行一次
-
- </script>
-
- </body>
- </html>
未完待续。。。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。