java调用ffmpeg命令行推流遇到的问题
1.Java调用命令行,如果没有额外环境变量,不指定工作路径,Runtime有两个方法
public Process exec(String command)
public Process exec(String cmdarray[])
ffmpeg推流本地视频命令如下
ffmpeg -re -i test.mp4 <param> <url>
ffmpeg -re -i test.mp4 <param> "<url> socks=***" // 代理
如果用exec(String command) 有代理的情况下,就算将双引号包含进去,也会不成功,会将<url>部分当做输入的视频文件位置。建议使用exec(String cmdarray[])方法。
在使用exec(String cmdarray[])时,内部处理是当如果中间有空格时,在首尾加上双引号,具体使用具体分析。
2.调用命令行后,程序可能正常推流推一会儿,然后程序block住,后台进程ffmpeg还没死。
Runtime.exec()执行时JVM会产生一个子进程,该进程与JVM建立三个通道链接:标准输入,标准输出,标准错误。
Java本地的系统对标准输入和输出所提供的缓冲池有限,所以错误的对标准输出快速的写入和从标准输入快速的读入都有可能造成子进程死锁。
子进程的输出流,也就是JVM的输入流。子进程不断向控制台输出,如果Java没有把输入流及时清空,会导致缓存区满,导致死锁。
解决办法就是及时清空输入流,开两个线程把process.getInputStream()和process.getErrorStream()读出来就可以。对于ffmpeg只需要process.getErrorStream()读出来就可以了。
Process process = Runtime.getRuntime().exec(command);
BufferedReader br= new BufferedReader(new InputStreamReader(process.getErrorStream()));
while ((line = br.readLine()) != null) {
System.out.println(line);
}
process.waitFor();
或者ProcessBuilder重定向标准错误
ProcessBuilder processBuilder = new ProcessBuilder(commands);
processBuilder.redirectErrorStream(true);
Process process = processBuilder.start(); ProcessContext.getInstance().addProcess(process); BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line = null;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
process.waitFor();
3.在虚拟机上测试时,模拟服务器瞬间断网的情况(拔网线),在虚拟机上跑的程序卡住了。
这种情况在正常服务器上没有问题,只在自己的虚拟机上有问题,原因不明,建议这种case在物理机上测试。
4.ffmpeg推本地视频文件时占用cpu过高,每个进程大约78-80%。
cpu主要是被图像转码占用了。如果是本地视频并且不需要对图像转码的情况,使用参数 -vcodec copy不进行转码只是复制。会大大减低cpu使用率(仅占用2%左右)。
如果就是有转码的需求,可以尝试参数 -threads 2。
帮助:
1.ffmepg推流的返回值(process.exitValue()),0为成功,其他失败。
2.使用process.waitFor()等待子进程。
3.-ss **:**:** 跳过指定时长,对参数位置有要求。
java调用ffmpeg命令行推流遇到的问题的更多相关文章
- 使用java执行ffmpeg命令进行推流操作
视频网站中提供的在线视频播放功能,播放的都是FLV格式的文件,它是Flash动画文件,可通过Flash制作的播放器来播放该文件.项目中用制作的player.swf播放器. 多媒体视频处理工具FFmpe ...
- java 调用 linux 命令行 +使用管道、awk等命令进行数据处理的方法
这里用 sh -c "命令" 的方式是因为java里只能这么用,管道这边java处理不了,所以只能一次执行一条命令,但是在linux里用 sh -c 的方式返回的awk处理过的结果 ...
- 搭建rtmp直播流服务之2:使用java实现ffmpeg命令接口化调用(用java执行ffmpeg命令)
欢迎大家积极开心的加入讨论群 群号:371249677 (点击这里进群) 一.环境搭建 1.安装ffmpeg 下载对应系统的ffmpeg安装包,个人采用windows平台进行开发,所以安装了windo ...
- Java调用FFmpeg进行视频处理及Builder设计模式的应用
1.FFmpeg是什么 FFmpeg(https://www.ffmpeg.org)是一套可以用来记录.转换数字音频.视频,并能将其转化为流的开源计算机程序.它用来干吗呢?视频采集.视频格式转化.视频 ...
- 【Andorid】短视频拍摄SDK——Vitamio Recorder 2.0 发布(支持ffmpeg命令行)
简介 VCamera SDK Android 版(短视频拍摄SDK)是炫一下(北京)科技有限公司推出的软件开发工具包,为Android开发者提供简单.快捷的接口,帮助开发者实现Android平台上的短 ...
- FFmpeg命令行工具和批处理脚本进行简单的音视频文件编辑
FFmpeg_Tutorial FFmpeg工具和sdk库的使用demo 一.使用FFmpeg命令行工具和批处理脚本进行简单的音视频文件编辑 1.基本介绍 对于每一个从事音视频技术开发的工程师,想必没 ...
- FFmpeg命令行工具学习(一):查看媒体文件头信息工具ffprobe
一.简述 ffprobe是ffmpeg命令行工具中相对简单的,此命令是用来查看媒体文件格式的工具. 二.命令格式 在命令行中输入如下格式的命令: ffprobe [文件名] 三.使用ffprobe查看 ...
- scala调用Linux命令行
在 scala 里面存在 调用 Linux 命令行的函数: import scala.sys.process._ 执行的方法也不难: import scala.sys.process._ /** * ...
- Java调用windows命令
JAVA调用windows的cmd命令 用起来会让程序变得更加简洁明了,非常实用. 核心就是使用 Runtime类. cmd的xcopy就有很强大的文件夹,文件处理功能. 下面就以xcopy来说明,如 ...
随机推荐
- 第二百二十六节,jQuery EasyUI,Tree(树)组件
jQuery EasyUI,Tree(树)组件 本节课重点了解 EasyUI 中 Tree(树)组件的使用方法,这个组件依赖于 Draggable(拖 动)和 Droppable(放置)组件. 一.加 ...
- 第二百一十二节,jQuery EasyUI,Combo(自定义下拉框)组件
jQuery EasyUI,Combo(自定义下拉框)组件 学习要点: 1.加载方式 2.属性列表 3.事件列表 4.方法列表 本节课重点了解 EasyUI 中 Combo(自定义下拉框)组件的使用方 ...
- 实现Netty服务器与CocosCreate通信
尽量采用无锁化Netty通信处理棋牌房间逻辑 一,棋牌类服务器的特点 1,棋牌类不分区不分服 一般来说,棋牌游戏都是不分区不分服的.所以棋牌类服务器要满足随着用户量的增加而扩展的需要,所以需要设计Ga ...
- C++学习之拷贝构造函数篇
一.拷贝构造函数的声明 Array(const Array & arr); 二.拷贝构造函数的实现分为两种,即是深拷贝和浅拷贝. 1.浅拷贝 代码例如以下: class Array { pub ...
- [翻译]在ASP.NET Web API中通过OData支持查询和分页
OData可以通过形如http://localhost/Products?$orderby=Name这样的QueryString传递查询条件.排序等.你可以在任何Web API Controller中 ...
- Torch-RNN运行过程中的坑 [1](读取Lua非空table,size为0)
0.踩坑背景 执行Torch-RNN的时候,在LanguageModel.lua中的encode_string函数中,对start_text的各个character进行id映射编码,实现功能类似“北京 ...
- js autoComplate
在实际的项目中,能用别人写好的插件实现相关功能是最好不过,为了节约时间成本,因为有的项目比较紧急,没充分时间让你自己来写,即便写了,你还要花大量时间调试兼容性.但是出于学习的目的,你可以利用闲暇时间, ...
- asp.net 读取配置文件方法
方法1: System.Collections.Specialized.NameValueCollection nvc = (System.Collections.Specialized.NameVa ...
- ASP.NET动态添加控件一例
第一次单击页面中有3个Label,第二次单击有6个,第三次单击有9个,也就是每次单击要在上次的状态下再添加3个. 我的方法是,可以通过Session来保存上次的状态,一种解法如下: Test.aspx ...
- gcc/g++ 实战之编译的四个过程
gcc和g++分别是GNU(一个开源组织)的c&c++编译器 对于.c后缀的文件,gcc把它当做是C程序,g++当做是C++程序:对于.cpp后缀的文件,gcc和g++都会当做c++程序. ...