Ffmpeg 从IP摄像头将RTSP流媒体传输到web浏览器的最佳方法?
是否可以将RTSP流式传输数据导入web浏览器 以下是我的一些发现。如果我错了,请纠正我。Ffmpeg 从IP摄像头将RTSP流媒体传输到web浏览器的最佳方法?,ffmpeg,websocket,activex,webbrowser-control,rtsp,Ffmpeg,Websocket,Activex,Webbrowser Control,Rtsp,是否可以将RTSP流式传输数据导入web浏览器 以下是我的一些发现。如果我错了,请纠正我。 只有Mac OS和Safari支持RTSP实时流媒体 HTML 5视频不支持RTSP 我可以使用VLC插件,但我不想使用它 混合ffmpeg和websocket的可能性? 假设我的IP摄像头与以太网连接 在客户端计算机中: 我运行ffmpeg从服务器获取数据(即:IP) 客户端计算机运行websocket 一旦ffmpeg从RTSP服务器获取数据,它将解码并生成任何格式的原始图像(例如:yuv) 现在,我
ffmpeg
将输入转换为MPEG1视频:
ffmpeg -i rtsp://whatever -f mpeg1video -b 800k -r 30 http://localhost:8082/yourpassword/640/480/
使用和ws
ws-WebSocket包中的stream server.js
脚本安装node.js
要查看流,请使用中的stream example.html
和jsmpg.js
。将stream example.html
中的WebSocket URL更改为localhost
,并在您喜爱的浏览器中打开它
更新建议另外两种工作解决方案,带有标签:使用Java server或使用
ffserver
我需要在不同的平台和浏览器中显示流媒体。为了在不使用任何插件的情况下实现这一点(不确定它是否能在智能手机和平板电脑上工作),我们使用了与您非常类似的方法。ffmpeg crontab任务每秒创建3个图像,并存储到目录中。使用Jquery,对php的ajax调用读取目录并获取文件名,每330ms更改一次图像(仅更改
的'src'属性)。为了解决存储问题,使用了其他crontab任务,在1分钟以上的时间内删除文件。它不是真正的流媒体,而是跨浏览器的,很好地解决了这个问题
ffmpeg任务
示例ajax调用
存储控制任务
ffmpeg -i "rtsp://path/to/cam" -s 320x240 -f image2 -vf fps=fps=3 cache/%04d.jpg
希望能有所帮助!:) 如果您只想将其流式传输到少数客户端,那么您可以使用直接运行ffmpeg的cgi(或在nodejs中,一个child_进程): NodeJS示例:
$.ajax({
url: '_read_dir.php',
type: 'POST',
dataType: 'json'
})
.done(function(result) {
$("#img_cam").prop('src',"cache/" + result.img);
});
CGI应该更加容易
在浏览器中,您可以
find /var/www/path/to/dir -mmin +1 -exec rm -f {} \;
(使用海报,因为视频可能需要几秒钟才能显示)
警告:
这将为您的设置的每个连接启动ffmpeg,因此它根本不会扩展。这应该只用于非常私人的网站,在那里连接是有限的(例如:仅限于您自己)。
PS:ffmpeg命令可能需要一些调整。vlc解决方案:
app.getExpressApp().get('/camera/feed', (req, res) => {
// Thanks to https://stackoverflow.com/q/28946904/1954789
const child_process = require('child_process');
res.header('content-type', 'video/webm');
const cmd = `ffmpeg -i rtsp://user:pwd@somewhere/videoSub -c:v copy -c:a copy -bsf:v h264_mp4toannexb -maxrate 500k -f matroska -`.split(' ');
var child = child_process.spawn(cmd[0], cmd.splice(1), {
stdio: ['ignore', 'pipe', process.stderr]
});
child.stdio[1].pipe(res);
res.on('close', () => {
// Kill ffmpeg if the flow is stopped by the browser
child.kill();
});
然后检查
http://localhost:8080/webcam.ogg
或者将此url集成到您想要运行的任何Web服务
如果您对vlc的python api感兴趣,下面是一个示例:
<video autoplay=1 poster="camera.png" ><source src="/camera/feed"></video>
scandir.php(由JS在viewcamera.php中使用)
streamcam.php(在crontab中运行)
这支持音频吗?理论上是这样的。我建议使用
标签更好。我的意思是,它是否仅通过使用视频标签就支持视频音频流?:)是,
标记同时支持这两种功能;但是准备相关的流是你的责任。我找不到stream-server.js脚本,你能进一步解释一下吗,目前我用nodejs设置了一个本地httpserver并安装了jsmpeg,谢谢。我相信这些天来,最好的方法是。我感到惊讶的是,6年前的这个问题仍然相关。我曾与他一起工作过,并且非常高兴。
cvlc -v rtsp://user:password@camera_ip_address --sout='#transcode{vcodec=theo,vb=800,acodec=vorb,ab=128,channels=2,samplerate=44100,scodedec=none}:http{dst=:8080/webcam.ogg}'
import vlc
class WebcamStreamer:
def __init__(self, config):
"""
Expected rtsp url format:
"rtsp://user:password@192.168.0.1"
"""
self.instance = vlc.Instance()
self.stream_name = "webcam".encode()
self.rtsp_url = config["rtsp_url"].encode()
def launch_webcam_stream_converter(self):
"""
Basically here is what is done:
cmd= ["cvlc", "-v", f"rtsp://user:password@192.168.0.16",
f"--sout='#transcode{{vcodec=theo,vb=800,acodec=vorb,ab=128,channels=2,samplerate=44100,scodedec=none}}:http{{dst=:8080/webcam.ogg}}'"]
subprocess.run(cmd)
"""
ret = vlc.libvlc_vlm_add_broadcast(
p_instance=self.instance,
psz_name=self.stream_name,
psz_input=self.rtsp_url,
psz_output=f"#transcode{{vcodec=theo,vb=800,acodec=vorb,ab=128,channels=2,samplerate=44100,scodedec=none}}:http{{dst=:8080/webcam.ogg}}".encode(),
i_options=0,
ppsz_options=[],
b_enabled=True,
b_loop=False
)
assert (ret == 0)
vlc.libvlc_vlm_play_media(self.instance, self.stream_name)
<?php
$folder = $_GET['name'];
$dir = "../cache/".$folder;
// Sort in descending order
$b = scandir($dir,1);
$myJSON = json_encode($b);
echo $myJSON;
?>
<?php
function live_view ($cameraip, $cameraname){
echo shell_exec("/usr/bin/ffmpeg -rtsp_transport tcp -i rtsp://root:pass@".$cameraip."/ufirststream -s 1920x1080 -f image2 -vf fps=fps=5 /var/www/html/occupancy/cache/".$cameraname."/frame%04d.jpg >/dev/null 2>/dev/null &");
}
<img width="100%" height="auto" id="img_cam<?php echo $camera_name_stripped;?>" src="">
<script>
var cameraName = $(e.relatedTarget).data('camera-name-stripped');
window.livetimer<?php echo $camera_name;?> = setInterval(function() {
<?php echo $camera_name_stripped;?> = $.ajax({
url: 'scandir.php?name='+cameraName,
type: "POST",
dataType: 'json'
}).done(function(result) {
$("#img_cam<?php echo $camera_name_stripped;?>").attr('src',"../cache/" + cameraName + "/" + result[0]);
});
}, 55);
});
</script>