视频监控实时播放的原理与目前较为流行的直播是一致的,所以采用直播的架构实现视频监控实时播放,流程图如下:
目前实时视频流的传输协议有以下几种:RTSP、RTMP、HLS、Http-flv。
安卓APP开发使用HBuilder,而HBuilder内置了LivePusher直播推流控件,该控件使用了RTMP协议,所以暂时选择使用RTMP协议
| 协议 | RTSP | RTMP | HLS | Http-flv |
|---|---|---|---|---|
| 实时预览 | √ | √ | √ | √ |
| 实时回放 | √ | √ | √ | √ |
| 定位 | √ | √ | √ | × |
| 暂停恢复 | √ | √ | √ | × |
| 视频加密 | √ | × | √ | √ |
| 视频格式 | H264/H265 | H264/H265 | H264 | H264/H265 |
| 音频格式 | G711u, G711a, G726, MP2L2, AAC | AAC | AAC | AAC |
| 首屏时间 | 1秒 | 1秒 | 3~4秒 | 1秒 |
| 播放延迟 | 1秒 | 1秒 | 3~4秒 | 1秒 |
RTMP服务器使用nginx+rtmp模块搭建,linux下可以下载nginx源代码+nginx-rtmp-module模块重新编译,windows下nginx编译较为麻烦,可以下载nginx 1.7.11.3 Gryphon,然后再下载nginx-rtmp-module模块进行配置即可
nginx地址:https://github.com/nginx/nginx
nginx-rtmp-module地址:https://github.com/arut/nginx-rtmp-module/
nginx 1.7.11.3 Gryphon地址:http://nginx-win.ecsds.eu/download/nginx 1.7.11.3 Gryphon.zip
ffmpeg地址:https://ffmpeg.org/download.html
在http段之前增加以下内容:
rtmp {
server {
listen 1935;
application live {
live on;
record off;
publish_notify on;
#on_publish http://localhost:8080/newsweb/api/v1/rtmp/on_publish;
#on_publish_done http://localhost:8080/newsweb/api/v1/rtmp/on_publish_done;
#on_play http://localhost:8080/newsweb/api/v1/rtmp/on_play;
#on_play_done http://localhost:8080/newsweb/api/v1/rtmp/on_play_done;
}
application hls {
live on;
hls on; #是否开启hls
hls_path temp/hls; #本地切片路径
hls_fragment 8s; #本地切片长度
publish_notify on;
#on_publish http://localhost:8080/newsweb/api/v1/rtmp/on_publish;
#on_publish_done http://localhost:8080/newsweb/api/v1/rtmp/on_publish_done;
#on_play http://localhost:8080/newsweb/api/v1/rtmp/on_play;
#on_play_done http://localhost:8080/newsweb/api/v1/rtmp/on_play_done;
}
}
}
在http->server下,location /段之前增加以下内容:
location /stat {
rtmp_stat all;
rtmp_stat_stylesheet stat.xsl;
}
location /stat.xsl {
root nginx-rtmp-module/;
}
#HLS配置开始,这个配置为了`客户端`能够以http协议获取HLS的拉流
location /hls {
#server hls fragments
types{
application/vnd.apple.mpegurl m3u8;
video/mp2t ts;
}
alias temp/hls;
expires -1;
}
注:其中rtmp段中的on_publish、on_publish_done、on_play、on_play_done是事件触发,当直播开始、直播结束、观看开始、观看结束时,会触发指定的URL,并将推流和观看时的相关参数传递到相关URL上,如果HTTP返回的状态码不是200时表示鉴权失败,会直接阻断下一步的操作
#推流地址解释:rtmp://localhost:1935/live/home?p=v
#rtmp://为协议名
#localhost是域名
#1935为端口号,rtmp默认为1935端口
#live为nginx.conf中配置的rtmp标记
#home为指定字符串,生产环境中可以设置为设备ID或用户ID
#?p=v是附加参数,用于鉴权和记录直播开始使用
#ffmpeg推流测试:
ffmpeg.exe -re -i c:\ffmpeg\inputfile.mp4 -vcodec libx264 -acodec aac -f flv rtmp://127.0.0.1:1935/live/home
#ffmpeg 拉流测试:
ffplay.exe rtmp://localhost:1935/live/home
安卓APP推流使用HBuilder的LivePusher直播推流控件,代码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no"/>
<title>Video Example</title>
<script type="text/javascript">
var pusher = null;
// H5 plus事件处理
function plusReady(){
// 创建直播推流控件
pusher = new plus.video.LivePusher('pusher',{
url:'rtmp://172.16.70.182:1935/live/phone',
mode:'SD',
muted:false,
});
pusher.preview();
// 监听状态变化事件
pusher.addEventListener('statechange', function(e){
console.log('statechange: '+JSON.stringify(e));
}, false);
}
document.addEventListener('plusready', plusReady, false);
// 设置推流服务器
function updatePusher() {
var url= document.getElementById('pushurl').value;
pusher.setOptions({
url:url
});
}
// 开始推流
function startPusher() {
console.log(pusher)
pusher.start();
}
// 切换摄像头
function switchCamera() {
pusher.switchCamera();
}
</script>
</head>
<body style="margin:0;padding:0;text-align:center;">
<div id="pusher" style="width:100%;height:300px;background-color:#000000;margin:auto"></div>
<br/>
<input type="text" id="pushurl" value="rtmp://172.16.70.182:1935/live/phone" style="width: 500px;"/> <br><br>
<button onclick="updatePusher()">更新推流服务器</button>
<br/><br>
<button onclick="startPusher()">开始推流</button>
<br><br>
<button onclick="switchCamera()">切换摄像头</button>
<br/><br/>
</body>
</html>
目前暂时使用VLC进行视频播放
VLC下载地址:https://www.videolan.org/vlc/
我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div
我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看rubyzip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
很好奇,就使用rubyonrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提
假设我做了一个模块如下:m=Module.newdoclassCendend三个问题:除了对m的引用之外,还有什么方法可以访问C和m中的其他内容?我可以在创建匿名模块后为其命名吗(就像我输入“module...”一样)?如何在使用完匿名模块后将其删除,使其定义的常量不再存在? 最佳答案 三个答案:是的,使用ObjectSpace.此代码使c引用你的类(class)C不引用m:c=nilObjectSpace.each_object{|obj|c=objif(Class===objandobj.name=~/::C$/)}当然这取决于
我正在尝试使用ruby和Savon来使用网络服务。测试服务为http://www.webservicex.net/WS/WSDetails.aspx?WSID=9&CATID=2require'rubygems'require'savon'client=Savon::Client.new"http://www.webservicex.net/stockquote.asmx?WSDL"client.get_quotedo|soap|soap.body={:symbol=>"AAPL"}end返回SOAP异常。检查soap信封,在我看来soap请求没有正确的命名空间。任何人都可以建议我
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t
我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h
我想为Heroku构建一个Rails3应用程序。他们使用Postgres作为他们的数据库,所以我通过MacPorts安装了postgres9.0。现在我需要一个postgresgem并且共识是出于性能原因你想要pggem。但是我对我得到的错误感到非常困惑当我尝试在rvm下通过geminstall安装pg时。我已经非常明确地指定了所有postgres目录的位置可以找到但仍然无法完成安装:$envARCHFLAGS='-archx86_64'geminstallpg--\--with-pg-config=/opt/local/var/db/postgresql90/defaultdb/po