首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

浏览器播放RTSP流,支持H264、H265等格式,支持IE、Chrome等浏览器

  • 25-02-19 03:41
  • 3832
  • 13780
blog.csdn.net

目录

背景

解决方案

效果

代码

前端代码

后端代码

下载


背景

项目中需要在浏览器中播放RTSP流,实在是不想折腾ActiveX控件

1、麻烦(开发麻烦、使用时设置也麻烦)

2、非IE浏览器不兼容

解决方案

使用OpenCvSharp+Nancy写一个解码服务,提供http接口,返回解码后Mat对象的Base64字符串,前端页面循环调用并展示。

效果

浏览器播放RTSP流

代码

前端代码




   
    rtsp播放测试
   
   


   


       

       

           

               

                    <span class="label label-primary">rtsp播放测试
                   

               

               

                   

                   

                   
                   
                   
                   
                   


                   
               

           

       

   



  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="UTF-8" />
  5. <title>rtsp播放测试</title>
  6. <link rel="stylesheet" href="bootstrap.min.css" />
  7. <script src="jquery-1.8.0.js" type="text/javascript"></script>
  8. </head>
  9. <body>
  10. <div class="container">
  11. <br />
  12. <div class="row">
  13. <div class="panel panel-primary">
  14. <div class="panel-heading">
  15. <span class="label label-primary">rtsp播放测试</span>
  16. <br />
  17. </div>
  18. <div class="panel-body">
  19. <input type="text" value="" id="txtRTSPURL" style="width: 500px;" /><br />
  20. <br />
  21. <input type="button" value="打开" id="btnOpen" />
  22. <input type="button" value="播放" id="btnPlay" />
  23. <input type="button" value="停止" id="btnStop" />
  24. <input type="button" value="测试获取一帧" id="btnTest" />
  25. </br> </br>
  26. <img id="imgId" src="" style="width: 1024px" />
  27. </div>
  28. </div>
  29. </div>
  30. </div>
  31. </body>
  32. <script type="text/jscript">
  33. $(function () {
  34. $("#btnOpen").click(function () {
  35. var rtsp_url = $("#txtRTSPURL").val();
  36. $.ajax({
  37. type: "post",
  38. url: base_url + "/open",
  39. dataType: 'json',
  40. data: { "rtsp_url": rtsp_url },
  41. success: function (d) {
  42. if (d.code == 1) {
  43. alert("打开成功")
  44. } else {
  45. alert("打开失败:" + d.message)
  46. }
  47. }
  48. })
  49. })
  50. $("#btnTest").click(function () {
  51. $.ajax({
  52. type: "post",
  53. url: base_url + "/getframe",
  54. dataType: 'json',
  55. data: "",
  56. success: function (d) {
  57. if (d.code == 1) {
  58. console.log(d.data);
  59. $("#imgId").attr("src", "data:image/jpg;base64," + d.data);
  60. } else {
  61. alert("播放失败:" + d.message)
  62. }
  63. }
  64. })
  65. })
  66. $("#btnPlay").click(function () {
  67. try {
  68. flag = true;
  69. showImage();
  70. } catch (e) {
  71. }
  72. })
  73. $("#btnStop").click(function () {
  74. flag = false;
  75. $.ajax({
  76. type: "post",
  77. url: base_url + "/close",
  78. dataType: 'json',
  79. data: "",
  80. success: function (d) {
  81. if (d.code == 1) {
  82. } else {
  83. alert("关闭失败:" + d.message)
  84. }
  85. }
  86. })
  87. })
  88. })
  89. var base_url = "http://127.0.0.1:8082";
  90. var flag = false;
  91. function showImage() {
  92. $.ajax({
  93. type: "post",
  94. url: base_url + "/getframe",
  95. dataType: 'json',
  96. data: "",
  97. success: function (d) {
  98. if (d.code == 1) {
  99. $("#imgId").attr("src", "data:image/jpg;base64," + d.data);
  100. if (flag) {
  101. showImage();
  102. }
  103. } else {
  104. alert("播放失败:" + d.message)
  105. }
  106. }
  107. })
  108. }
  109. </script>
  110. </html>

后端代码

  1. using Nancy;
  2. using Newtonsoft.Json;
  3. using NLog;
  4. using OpenCvSharp;
  5. using OpenVINO.OCRService.Common;
  6. using System;
  7. using System.Threading;
  8. using System.Threading.Tasks;
  9. namespace CaptureService
  10. {
  11. public class CaptureModule : NancyModule
  12. {
  13. private Logger _log = NLog.LogManager.GetCurrentClassLogger();
  14. public static readonly object _locker = new object();
  15. public CaptureModule()
  16. {
  17. //跨域处理
  18. After.AddItemToEndOfPipeline((ctx) => ctx.Response
  19. .WithHeader("Access-Control-Allow-Origin", "*")
  20. .WithHeader("Access-Control-Allow-Methods", "POST,GET,OPTIONS")
  21. .WithHeader("Access-Control-Allow-Headers", "Accept, Origin, Content-type"));
  22. Get("/", p =>
  23. {
  24. return "Hello MediaCaptureService";
  25. });
  26. Post("/open", p =>
  27. {
  28. AjaxReturn ar = new AjaxReturn();
  29. if (Program.open)
  30. {
  31. ar.code = 0;
  32. ar.message = "已开启,如需重新开启,请先关闭!";
  33. _log.Info(JsonConvert.SerializeObject(ar));
  34. return Response.AsJson<AjaxReturn>(ar);
  35. }
  36. string rtsp_url = Request.Form["rtsp_url"];
  37. if (string.IsNullOrEmpty(rtsp_url))
  38. {
  39. ar.code = 0;
  40. ar.message = "参数[rtsp_url]不能为空";
  41. _log.Info(JsonConvert.SerializeObject(ar));
  42. return Response.AsJson<AjaxReturn>(ar);
  43. }
  44. Program.rtsp_url = rtsp_url;
  45. Program.ctsCapture = new CancellationTokenSource();
  46. Program.open = true;
  47. try
  48. {
  49. Task.Factory.StartNew(() =>
  50. {
  51. Program.capture = new VideoCapture(Program.rtsp_url);
  52. if (Program.capture.IsOpened())
  53. {
  54. int index = 0;
  55. Mat frame = new Mat();
  56. while (true)
  57. {
  58. if (Program.ctsCapture.IsCancellationRequested) break;
  59. Program.capture.Read(frame);
  60. if (Program.matQueue.Count >= 5)
  61. {
  62. continue;
  63. }
  64. Program.matQueue.Enqueue(frame);
  65. //_log.Info(Program.matQueue.Count);
  66. //Cv2.ImWrite(index + ".jpg", frame);
  67. //index++;
  68. }
  69. if (Program.capture != null)
  70. {
  71. Program.capture.Release();
  72. }
  73. }
  74. });
  75. ar.code = 1;
  76. ar.message = "success";
  77. }
  78. catch (Exception ex)
  79. {
  80. ar.code = 0;
  81. ar.message = ex.Message;
  82. _log.Error(ex, "开启异常");
  83. }
  84. return Response.AsJson<AjaxReturn>(ar);
  85. });
  86. Post("/close", p =>
  87. {
  88. AjaxReturn ar = new AjaxReturn();
  89. try
  90. {
  91. Program.open = false;
  92. if (Program.ctsCapture != null)
  93. {
  94. Program.ctsCapture.Cancel();
  95. }
  96. ar.code = 1;
  97. ar.message = "success";
  98. }
  99. catch (Exception ex)
  100. {
  101. ar.code = 0;
  102. ar.message = ex.Message;
  103. _log.Error(ex, "关闭异常");
  104. }
  105. return Response.AsJson<AjaxReturn>(ar);
  106. });
  107. Post("/getframe", p =>
  108. {
  109. AjaxReturn ar = new AjaxReturn();
  110. if (!Program.open)
  111. {
  112. ar.code = 0;
  113. ar.message = "网络流未打开,请先打开!";
  114. _log.Info(JsonConvert.SerializeObject(ar));
  115. return Response.AsJson<AjaxReturn>(ar);
  116. }
  117. if (Program.matQueue.Count == 0)
  118. {
  119. ar.code = 1;
  120. ar.message = "图像队列为空";
  121. _log.Info(JsonConvert.SerializeObject(ar));
  122. return Response.AsJson<AjaxReturn>(ar);
  123. }
  124. try
  125. {
  126. Mat frame = new Mat();
  127. if (!Program.matQueue.TryDequeue(out frame))
  128. {
  129. ar.code = 0;
  130. ar.message = "获取图像失败";
  131. _log.Info(JsonConvert.SerializeObject(ar));
  132. return Response.AsJson<AjaxReturn>(ar);
  133. }
  134. ar.code = 1;
  135. ar.message = "success";
  136. var bytes = frame.ToBytes();
  137. ar.data = Convert.ToBase64String(bytes);
  138. }
  139. catch (Exception ex)
  140. {
  141. ar.code = 0;
  142. ar.message = ex.Message;
  143. _log.Error(ex, "获取摄像头画面异常");
  144. }
  145. return Response.AsJson<AjaxReturn>(ar);
  146. });
  147. }
  148. }
  149. }

下载

源码下载

天天代码码天天
微信公众号
.NET 人工智能实践
注:本文转载自blog.csdn.net的天天代码码天天的文章"https://lw112190.blog.csdn.net/article/details/141615040"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

101
推荐
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2025 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top