ffmpeg 截图太模糊了_通过ffmpeg实现视频流截图

本文介绍了如何使用ffmpeg从视频流中截取清晰图片,重点在于解决ffmpeg截图模糊问题。通过Java调用ffmpeg脚本,实现了SSH远程执行截图命令,并探讨了后续将截图功能做成服务的可能性和硬件需求。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近忙于新产品技术点突破,针对架构摸索暂时停住。目前需要解决的问题是如何从视频流中截取一张图。

概况

在安防领域有各种视频监控产品,它们遵循的通讯协议也不尽相同,归纳起来主要遵循GB/T 28181、ONVIF、PSIA等协议。

GB/T 28181协议

其通信协议如下所示

通信协议结构图.png

其视频编码格式主要有:MPEG-4、H.264、SVAC等,目前主流的视频编码格式是H.264。

其实时传输协议为RTP,在此传输协议基础上对视音频数据进行封装,其又分为PS封装和非PS封装:

基于RTP的PS封装,是将视音频流封装成PS包,再将PS包以负载的方式封装成RTP包。

基于RTP的非PS封装,是直接将视音频流以负载的方式封装成RTP包。

如果对RTP协议感兴趣可以参考:

RTP协议分析

RTSP/RTP/RTCP详解整理

RTP协议全解析(H264码流和PS流)

RTP/RTSP/RTCP有什么区别?

Wireshark 抓包分析 RTSP/RTP/RTCP 基本工作过程

公司装有一台宇视的电警卡口抓拍机HC161智能交通600万摄像单元,可以看出该电警搭载的网络摄像头支持ONVIF、GB/T28181等协议,同时查看其视频配置

视频配置.png

可以尝试通过VLC连接RTSP视频流

vlc.png

安装ffmpeg

在CentOS7上安装ffmpeg

yum -y install epel-release

rpm --import http://li.nux.ro/download/nux/RPM-GPG-KEY-nux.ro

rpm -Uvh http://li.nux.ro/download/nux/dextop/el7/x86_64/nux-dextop-release-0-1.el7.nux.noarch.rpm

yum search ffmpeg

yum -y install ffmpeg ffmpeg-devel

ffmpeg -version

version.png

ffmpeg -y -i rtsp://user:password@ip:port-ss 00:00:01 -vframes 1 -f image2 -vcodec png image.png

image.png

Java调用脚本

脚本正确调用,接下来就通过Java调用远程服务器上脚本实现视频流截图,在此借助Ganymed SSH-2 for Java,实现SSH远程执行脚本。

package com.dhl.runshell;

import ch.ethz.ssh2.Connection;

import ch.ethz.ssh2.Session;

import ch.ethz.ssh2.StreamGobbler;

import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStream;

import java.io.InputStreamReader;

/**

* Created by daihl on 2017/10/10.

*/

public class CommandRunner {

public static Connection getOpenedConnection(String host, String username, String password) throws IOException {

Connection conn = new Connection(host);

conn.connect(); // make sure the connection is opened

boolean isAuthenticated = conn.authenticateWithPassword(username, password);

if (isAuthenticated == false)

throw new IOException("Authentication failed.");

return conn;

}

public static String execShellScript(String host, String username,

String password,

String cmd, int port) throws IOException {

Connection conn = null;

Session sess = null;

InputStream stdout = null;

BufferedReader br = null;

StringBuffer buffer = new StringBuffer("exec result:");

buffer.append(System.getProperty("line.separator"));// 换行

try {

conn = getOpenedConnection(host, username, password);

sess = conn.openSession();

sess.execCommand(cmd);

stdout = new StreamGobbler(sess.getStdout());

br = new BufferedReader(new InputStreamReader(stdout));

while (true) {

// attention: do not comment this block, or you will hit

// NullPointerException

// when you are trying to read exit status

String line = br.readLine();

if (line == null)

break;

buffer.append(line);

buffer.append(System.getProperty("line.separator"));// 换行

}

} finally {

sess.close();

conn.close();

}

return buffer.toString();

}

public static void main(String[] args) {

String cmd = "ffmpeg -y -i rtsp://user:password@ip:port -ss 00:00:01 -vframes 1 -f image2 -vcodec png image.png;echo end";

try {

String info = CommandRunner.execShellScript("ip", "user",

"password",cmd,22);

System.out.println("info is:"+info);

} catch (IOException e) {

e.printStackTrace();

}

}

}

后继工作

通过SSH远程执行脚本有点简单粗暴,何不将这截图功能做成服务,向外发布,更加灵活方便。故后期工作如下:

准备一台图片服务器,其主要职责有

1.图片文件存储

2.响应终端的抓图请求,并将图片保存到指定文件夹目录下

3.响应终端的合图请求,以上两者做成服务的形式,终端通过分布式调用服务,完成操作并返回结果状态

4.接收终端上传的图片

硬件需求:

1.因图片服务器上安装ffmpeg工具,其需要对视频流进行解码,并按照png格式组织编码,对计算性能要求高,所以CPU性能要好

2.作为图片文件存储服务器,存储容量要大

3.接受多终端设备连接,网口带宽要大

后记

因为要接收反馈结果,cmd命令可以这样写

rtsp://user:password@ip:port -ss 00:00:01 -vframes 1 -f image2 -vcodec png image.png && echo succeeded ||echo failed

当ffmpeg执行正确时,会输出succeeded,当ffmpeg不能正确执行时,会输出failed

新建目录文件夹,将截图文件放入指定文件夹中

if [ ! -d /home/daihl/$(date +%Y%m%d) ]; then mkdir -p /home/daihl/$(date +%Y%m%d)&&echo "mkdir"; fi

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值