欢迎大家积极开心的加入讨论群

一、环境搭建

1、安装ffmpeg

下载对应系统的ffmpeg安装包,个人采用windows平台进行开发,所以安装了windows版本(各平台ffmpeg命令都是一样的,无须纠结)

2、ffmpeg的命令

这里不在详述,在这里会用简单的命令即可,后面我会写篇专门介绍ffmpeg的命令的文章

二、使用Java实现ffmpeg的命令调用的接口化可管理

1、java解析ffmpeg命令解析及动态实现

这是rtmp直播流服务器的发布地址:rtmp://192.168.30.21/live/

如果新发布一个视频,可以增加一个应用名,比如

rtmp://192.168.30.21/live/test2

或者

rtmp://192.168.30.21/live/DahuaCamera

注释写的很全,这里就不在做过多叙述

<span style="font-size:18px;">  /**
* 通过解析参数生成可执行的命令行字符串;
* name:应用名;input:接收地址;output:推送地址;fmt:视频格式;fps:视频帧率;rs:视频分辨率;disableAudio:是否开启音频
*
* @param paramMap
* @return 命令行字符串
*/
protected String getComm4Map(Map<String, Object> paramMap)
{
// -i:输入流地址或者文件绝对地址
StringBuilder comm = new StringBuilder("ffmpeg -i ");
// 是否有必输项:输入地址,输出地址,应用名
if (paramMap.containsKey("input") && paramMap.containsKey("output")
&& paramMap.containsKey("name"))
{
comm.append(paramMap.get("input")).append(" ");
// -f :转换格式,默认flv
comm.append(" -f ").append(paramMap.containsKey("fmt") ? paramMap.get("fmt") : "flv").append(" ");
// -r :帧率,默认25
comm.append("-r ").append(paramMap.containsKey("fps") ? paramMap.get("fps") : "30").append(" ");
// -s 分辨率 默认是原分辨率
comm.append("-s ").append(paramMap.containsKey("rs") ? paramMap.get("rs") : "").append(" ");
// -an 禁用音频
comm.append("-an ").append(paramMap.containsKey("disableAudio") && ((Boolean)paramMap.get("disableAudio")) ? "-an" : "").append(" ");
// 输出地址
comm.append(paramMap.get("output"));
//发布的应用名
comm.append(paramMap.get("name"));
//一个视频源,可以有多个输出,第二个输出为拷贝源视频输出,不改变视频的各项参数
comm.append(" ").append(" -vcodec copy -f flv -an rtmp://192.168.30.21/live/test2");
System.out.println(comm.toString());
return comm.toString();
}
else
{
throw new RuntimeException("输入流地址不能为空!");
} }</span>

2、执行ffmpmeg命令

2.1、上一步已经可以动态的创建ffmpeg的命令了,这一步我们要让命令执行

<span style="font-size:18px;">  final Process proc = Runtime.getRuntime().exec(comm);
System.out.println("执行命令----start commond");
OutHandler errorGobbler = new OutHandler(proc.getErrorStream(), "Error");
OutHandler outputGobbler = new OutHandler(proc.getInputStream(), "Info"); errorGobbler.start();
outputGobbler.start();</span>

2.2、在执行ffmpeg命令时必须开启两个输出线程(上面代码中的OutHandler类)

OutHandler类实现了Thread接口,并且重写了注销该线程的方法(用于关闭该线程)

具体实现是这样的:

<span style="font-size:18px;">import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader; /**
* 用于输出命令行主进程的消息线程(必须开启,否则命令行主进程无法正常执行) 重要:该类重写了destroy方法,用于安全的关闭该线程
*
* @author eguid
* @see OutHandler
* @since jdk1.7
*/ public class OutHandler extends Thread
{
// 控制线程状态
volatile boolean status = true; BufferedReader br = null; String type = null; public OutHandler(InputStream is, String type)
{
br = new BufferedReader(new InputStreamReader(is));
this.type = type;
} /**
* 重写线程销毁方法,安全的关闭线程
*/
@Override
public void destroy()
{
status = false;
} /**
* 执行输出线程
*/
@Override
public void run()
{
String msg = null;
try
{
while (status)
{ if ((msg = br.readLine()) != null)
{
System.out.println(type + "消息:" + msg);
}
}
}
catch (IOException e)
{
e.printStackTrace();
}
} }
</span>

2.3、实现统一关闭命令行主进程和关联的两个输出线程

现在命令行已经可以执行了,但是却没法关闭它和关联的两个输出线程,怎么办?

我们在上面代码中已经重写了输出线程的注销方法,只要能够得到这两个线程我们就能关闭它们;

命令行主进程也是同样,只需要获得该进程Process即可使用destroy()方法进行关闭。

2.3.1、实现(把主进程Process和两个OutHandler返回给上一级,让上一级统一存放并管理他们):
<span style="font-size:18px;"> public ConcurrentMap<String, Object> push(Map<String, Object> paramMap)
throws IOException
{
// 从map里面取数据,组装成命令
String comm = getComm4Map(paramMap);
ConcurrentMap<String, Object> resultMap = null;
// 执行命令行
final Process proc = Runtime.getRuntime().exec(comm);
System.out.println("执行命令----start commond");
OutHandler errorGobbler = new OutHandler(proc.getErrorStream(), "Error");
OutHandler outputGobbler = new OutHandler(proc.getInputStream(), "Info"); errorGobbler.start();
outputGobbler.start();
// 返回参数
resultMap = new ConcurrentHashMap<String, Object>();
resultMap.put("info", outputGobbler);
resultMap.put("error", errorGobbler);
resultMap.put("process", proc);
return resultMap;
}</span>
2.3.2、父级这样实现关闭主进程和两个输出线程(必须先关闭两个输出线程):
<span style="font-size:18px;"> public void removePush(String pushId)
{
if (hd.isHave(pushId))
{
ConcurrentMap<String, Object> map = hd.get(pushId);
//关闭两个线程
((OutHandler)map.get("error")).destroy();
((OutHandler)map.get("info")).destroy(); System.out.println("停止命令-----end commond");
//关闭命令主进程
((Process)map.get("process")).destroy();
hd.delete(pushId);
}
}</span>
2.3.3、简单使用map存放Process和OutHandler
<span style="font-size:18px;"> private static ConcurrentMap<String, ConcurrentMap<String, Object>> handlerMap = new ConcurrentHashMap<String, ConcurrentMap<String, Object>>(20);
</span>

到这里,我们就可以做到动态创建、运行并关闭ffmpeg命令的功能

简单测试一下能不能正常发布视频流到rtmp直播流服务器

<span style="font-size:18px;">//name:应用名;input:接收地址;output:推送地址;fmt:视频格式;fps:视频帧率;rs:视频分辨率;disableAudio:是否开启音频
PushManager pusher = new PushManagerImpl();
Map map=new HashMap();
map.put("name", "test3");
map.put("input", "rtsp://admin:admin@192.168.2.236:37779/cam/realmonitor?channel=1&subtype=0");
map.put("output", "rtmp://192.168.30.21/live/");
map.put("fmt", "flv");
map.put("fps", "25");
map.put("rs", "640x360");
map.put("disableAudio", true);
//推送后会获得该处理器的id,通过该id可关闭推送流
String id = pusher.push(map);
Thread.sleep(100000);
//关闭推送流
pusher.removePush(id);</span>

通过输出线程输出的消息可以看到直播流发布成功了

搭建rtmp直播流服务之2:使用java实现ffmpeg命令接口化调用(用java执行ffmpeg命令)的更多相关文章

  1. 搭建rtmp直播流服务之3:java开发ffmpeg实现rtsp转rtmp并实现ffmpeg命令的接口化管理架构设计及代码实现

    上一篇文章简单介绍了java如何调用ffmpeg的命令:http://blog.csdn.net/eguid_1/article/details/51777716 上上一篇介绍了nginx-rtmp服 ...

  2. 搭建rtmp直播流服务之1:使用nginx搭建rtmp直播流服务器(nginx-rtmp模块的安装以及rtmp直播流配置)

    欢迎大家积极开心的加入讨论群 群号:371249677 (点击这里进群) 一.方案简要 首先通过对开发方案的仔细研究(实时监控.流媒体.直播流方案的数据源-->协议转换-->服务器--&g ...

  3. 搭建rtmp直播流服务之4:videojs和ckPlayer开源播放器二次开发(播放rtmp、hls直播流及普通视频)

    前面几章讲解了使用 nginx-rtmp搭建直播流媒体服务器; ffmpeg推流到nginx-rtmp服务器; java通过命令行调用ffmpeg实现推流服务; 从数据源获取,到使用ffmpeg推流, ...

  4. 三、直播整体流程 五、搭建Nginx+Rtmp直播流服务

    HTML5实现视频直播功能思路详解_html5教程技巧_脚本之家 https://m.jb51.net/html5/587215.html 三.直播整体流程 直播整体流程大致可分为: 视频采集端:可以 ...

  5. 极速搭建RTMP直播流服务器+webapp (vue) 简单实现直播效果

    在尝试使用webRTC实现webapp直播失败后,转移思路开始另外寻找可行的解决方案.在网页上尝试使用webRTC实现视频的直播与看直播,在谷歌浏览器以及safari浏览器上测试是可行的.但是基于基座 ...

  6. nginx开发(四)调用ffmpeg,搭建rtmp直播流。

    1: 修改conf文件,配置rtmp直播 打开usr/local/nginx/conf/nginx.conf,添加红色内容: rtmp {#rtmp点播配置    server {        li ...

  7. 利用docker搭建RTMP直播流服务器实现直播

    一.rtmp服务器搭建 环境: centos 7.* 1.先安装docker(省略) 2.下载docker容器 docker pull alfg/nginx-rtmp 3.运行容器(记得打开防火墙端口 ...

  8. 搭建RTMP直播流服务器

    最近项目比较紧张,所以没什么时间写博客,正好这几天没什么事,赶紧记录下自己最近所学. 环境配置 服务器选用 服务器我选择的是小鸟云 ,原因很简单,他的个人用户有3个月免费使用时间. 服务器环境 Win ...

  9. 实时监控、直播流、流媒体、视频网站开发方案流媒体服务器搭建及配置详解:使用nginx搭建rtmp直播、rtmp点播、,hls直播服务配置详解

    注意:这里不会讲到nginx流媒体模块如何安装的问题,只研究rtmp,hls直播和录制相关的nginx服务器配置文件的详细用法和说明.可以对照这些命令详解配置nginx -rtmp服务 一.nginx ...

随机推荐

  1. Elasticsearch - 快速入门

    Elasticsearch是基于Apache 2.0开源的实时.分布式.分析搜索引擎,相比Lucene,Elasticsearch的上手比较容易,这篇文章主要纪录Elasticsearch的基本概念和 ...

  2. Angular2.js——表单(下)

    这部分是接表单上部分的内容,主要内容有: 1.添加自定义的CSS来提供视觉反馈: 2.显示和隐藏有效性验证的错误信息: 3.使用ngSubmit处理表单提交: 4.禁用表单提交按钮. 添加自定义的CS ...

  3. [ext4]08 磁盘布局 - CheckSums

    从2012年开始,Ext4和jbd2的元数据中都开始加入checksums.特性标识是metadata_csum.Checksum算法是在super_block中指定: struct ext4_sup ...

  4. 详解Session分布式共享(.NET CORE版)

    一.前言&回顾 在上篇文章Session分布式共享 = Session + Redis + Nginx中,好多同学留言问了我好多问题,其中印象深刻的有:nginx挂了怎么办?采用Redis的S ...

  5. Transform java future into completable future 【将 future 转成 completable future】

    Future is introduced in JDK 1.5 by Doug Lea to represent "the result of an asynchronous computa ...

  6. Yeelink初步体验

    环境 Qemu: 2.8.0 开发板:vexpress-ca9   概述     前面的博文已经使我们的虚拟开发板具备了访问外网的目的,离物联网越来越近了.要玩物联网,Yeelink不得不说,它提供了 ...

  7. TreeSet对非自然顺序元素的排序

    /* 1. 往TreeSet添加元素的时候,如果元素本身具备了自然顺序的特性,那么就按照元素自然顺序的特性进行排序存储. 2. 往TreeSet添加元素的时候,如果元素本身不具备自然顺序的特性,那么该 ...

  8. sqlmap连接Mysql实现getshell(原创)

    前言 昨天群友发了一知乎的帖子..才发现sqlmap玩了那么久有些玩意我居然没玩过...然后看着群友玩= =今天也想试试. 0x01 首先得知道这个玩意,sqlmap -help,不说大家也懂搜嘎. ...

  9. Kafka学习-Producer和Customer

    在上一篇kafka入门的基础之上,本篇主要介绍Kafka的生产者和消费者. Kafka 生产者 kafka Producer发布消息记录到Kakfa集群.生产者是线程安全的,可以在多个线程之间共享生产 ...

  10. window 远程在Linux(centOS7.0)上安装JDK以及配置环境变量

    本人是在windows 7 上安装了虚拟机,虚拟机安装的是linux(centOS7.0)系统现在在Windows 上安装SecureCRT 远程虚拟机的linux系统,安装JDK以及配置环境变量. ...