当前位置:   article > 正文

获取视频 RTMP 推流web播放_网页如何播放rtmp流

网页如何播放rtmp流

工作需要研究下市面上显示实时视频方案。这里介绍下RTMP协议。

需求获取USB摄像头,手机谁摄像头。显示到web网页上。

一、 采集摄像头

这个使用opencvSharp来采集:

nuget:

 

  1. var task = Task.Run(() =>
  2. {
  3. var capture = new VideoCapture(0);
  4. VideoCaptureProperties captureProperties = new VideoCaptureProperties();
  5. capture.Fps = 30;
  6. //苹果测试流
  7. //var capture = new VideoCapture("http://devimages.apple.com.edgekey.net/streaming/examples/bipbop_4x3/gear2/prog_index.m3u8", VideoCaptureAPIs.FFMPEG);
  8. if (!capture.IsOpened())
  9. {
  10. ShowContent("Failed to open capture");
  11. return;
  12. }
  13. //capture.Set(captureProperties, 80);
  14. var frame = new Mat();
  15. var process = new Process();
  16. while (true)
  17. {
  18. capture.Read(frame);
  19. if (frame.Size().Width > 0 && frame.Size().Height > 0)
  20. {
  21. HersheyFonts fontFace = new HersheyFonts();
  22. frame.PutText(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), new OpenCvSharp.Point(10, 30), fontFace, 1.0, Scalar.Red);
  23. //var buffer = frame.ToBytes();
  24. //byte[] bytes = frame.ToBytes(".jpg");
  25. #region 压缩尺寸变小
  26. //Cv2.Resize(frame, frame, new OpenCvSharp.Size(frame.Width / 2, frame.Height / 2));
  27. byte[] bytes = CompressImEncode(frame); //CompressImEncodeNew(frame); //
  28. //预览压缩
  29. frame = Mat.FromImageData(bytes);
  30. #endregion
  31. MatToBitmapShow(frame);
  32. MemoryStream memory = new MemoryStream();
  33. memory.Write(bytes, 0, bytes.Length);
  34. memory.Write(_delimiter, 0, _delimiter.Length);
  35. SendTCP(memory.ToArray());
  36. //Cv2.ImShow("Video", frame);
  37. //Cv2.WaitKey(1);
  38. // 延时一段时间
  39. Cv2.WaitKey(1);
  40. }
  41. }
  42. });

二、 准备RTMP 流服务器 

 这里使用 nginx-rtmp-http-flv

  1. worker_processes 1;
  2. events {
  3. worker_connections 1024;
  4. }
  5. rtmp {
  6. server {
  7. listen 1935;
  8. application live {
  9. live on;
  10. ##打开 GOP 缓存,减少首屏等待时间
  11. gop_cache on ; #打开GOP缓存,减少首屏等待时间
  12. record_max_size 1K; #设置录制文件的最大值。
  13. }
  14. }
  15. }
  16. #推流地址:rtmp://192.168.1.194:1935/live/video1
  17. #FLV 播放地址:http://127.0.0.1:8088/flv?port=1935&app=live&stream=video1
  18. http {
  19. include mime.types;
  20. default_type application/octet-stream;
  21. sendfile on;
  22. keepalive_timeout 65;
  23. server {
  24. listen 8088;
  25. server_name localhost;
  26. location / {
  27. add_header 'Access-Control-Allow-Origin' '*';
  28. root html;
  29. index index.html index.htm;
  30. }
  31. location /live {
  32. flv_live on;
  33. }
  34. location /flv {
  35. add_header 'Access-Control-Allow-Origin' '*';
  36. flv_live on;
  37. chunked_transfer_encoding on;
  38. }
  39. error_page 500 502 503 504 /50x.html;
  40. location = /50x.html {
  41. root html;
  42. }
  43. }
  44. }

推流到流媒体服务器:

  1. string rtmp1 = "rtmp://127.0.0.1:1935/live/video1";
  2. string rtmp2 = "rtmp://127.0.0.1/live/test110";
  3. task = Task.Run(() =>
  4. {
  5. // 初始化 FFmpeg 库
  6. var capture = new VideoCapture(0);
  7. //var capture = new VideoCapture("http://devimages.apple.com.edgekey.net/streaming/examples/bipbop_4x3/gear2/prog_index.m3u8", VideoCaptureAPIs.FFMPEG);
  8. if (!capture.IsOpened())
  9. {
  10. ShowContent("Failed to open capture");
  11. return;
  12. }
  13. var frame = new Mat();
  14. var process = new Process();
  15. process.StartInfo.FileName = "ffmpeg";
  16. //aac 音频 -r 25 帧率25 -acodec aac
  17. process.StartInfo.Arguments = "-re -i - -vcodec libx264 -f flv " + rtmp1;
  18. process.StartInfo.UseShellExecute = false;
  19. process.StartInfo.RedirectStandardInput = true;
  20. //下面这设置使其后台运行
  21. process.StartInfo.CreateNoWindow = true;
  22. process.Start();
  23. while (true)
  24. {
  25. capture.Read(frame);
  26. if (frame.Size().Width > 0 && frame.Size().Height > 0)
  27. {
  28. HersheyFonts fontFace = new HersheyFonts();
  29. frame.PutText(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), new OpenCvSharp.Point(10, 30), fontFace, 1.0, Scalar.Red);
  30. var buffer = frame.ToBytes();
  31. process.StandardInput.BaseStream.Write(buffer, 0, buffer.Length);
  32. MatToBitmapShow(frame);
  33. //Cv2.ImShow("Video", frame);
  34. //Cv2.WaitKey(1);
  35. }
  36. }
  37. process.WaitForExit();
  38. });

三、网页播放:

效果:

 

  1. <!DOCTYPE html><html><head>
  2. <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
  3. <title>flv.js demo</title>
  4. <style>
  5. .mainContainer { display: block; width: 1024px; margin-left: auto; margin-right: auto;
  6. } .urlInput { display: block; width: 100%; margin-left: auto; margin-right: auto; margin-top: 8px; margin-bottom: 8px;
  7. } .centeredVideo { display: block; width: 100%; height: 576px; margin-left: auto; margin-right: auto; margin-bottom: auto;
  8. } .controls { display: block; width: 100%; text-align: left; margin-left: auto; margin-right: auto;
  9. }
  10. </style>
  11. </head>
  12. <body>
  13. <h1>FLV </h1>
  14. <div class="mainContainer">
  15. <video id="videoElement" class="centeredVideo" controls autoplay width="1024" height="576">Your browser is too old which doesn't support HTML5 video.</video>
  16. </div>
  17. <br>
  18. <div class="controls">
  19. <!--<button onclick="flv_load()">加载</button>-->
  20. <button onclick="flv_start()">开始</button>
  21. <button onclick="flv_pause()">暂停</button>
  22. <button onclick="flv_destroy()">停止</button>
  23. <input style="width:100px" type="text" name="seekpoint" />
  24. <button onclick="flv_seekto()">跳转</button>
  25. </div>
  26. <script src="flv.min.js"></script>
  27. <script>
  28. var player = document.getElementById('videoElement');
  29. if (flvjs.isSupported()) {
  30. var flvPlayer = flvjs.createPlayer({
  31. type: 'flv',
  32. "isLive": true,//<====加个这个
  33. url: 'http://192.168.1.194:8088/flv?port=1935&app=live&stream=video1',//<==自行修改
  34. //url: 'http://127.0.0.1:8080/live/test110.flv',
  35. });
  36. flvPlayer.attachMediaElement(videoElement);
  37. flvPlayer.load(); //加载
  38. flv_start();
  39. }
  40. function flv_start() {
  41. player.play();
  42. }
  43. function flv_pause() {
  44. player.pause();
  45. }
  46. function flv_destroy() {
  47. player.pause();
  48. player.unload();
  49. player.detachMediaElement();
  50. player.destroy();
  51. player = null;
  52. }
  53. function flv_seekto() {
  54. player.currentTime = parseFloat(document.getElementsByName('seekpoint')[0].value);
  55. }
  56. $(function(){
  57. flv_start();
  58. });
  59. // setInterval(() => {
  60. // if (this.player.buffered.length) {
  61. // let end = this.player.buffered.end(0);//获取当前buffered值
  62. // let diff = end - this.player.currentTime;//获取buffered与currentTime的差值
  63. // if (diff >= 0.5) {//如果差值大于等于0.5 手动跳帧 这里可根据自身需求来定
  64. // this.player.currentTime = this.player.buffered.end(0);//手动跳帧
  65. // }
  66. // }
  67. // }, 2000); //2000毫秒执行一次
  68. </script>
  69. </body>
  70. </html>

未完待续。。。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/112263
推荐阅读
相关标签
  

闽ICP备14008679号