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来说明,如 ...
随机推荐
- SQLServer 批量备份与还原
备份与还原是数据库避不开的主题,而作为DBA,经常会面临将一台机器上的所有数据库重新构建到一台新机器上的要求: 在现在都讲究自动化管理的时代,传统的界面操作备份还原的做法不仅浪费时间和精力,而且还很容 ...
- Python中3元运算符的实现
这是今天在温习lambda表达式的时候想到的问题,众所周知C系列语言中的 三元运算符(?:)是一个非常好用的语句, 关于C中的三元运算符表达式1?表达式2:表达式3 那么在python应该如何实现呢, ...
- smartJS 0.1 API 讲解 - Trigger
上篇介绍了PromiseEvent,本篇介绍Trigger - 基于Promise的aop的体现:(感觉自己的对这些命名一直都很挫,也懒得想了,所以就凑合的用) Trigger 在目标对象上加入触发器 ...
- 【ARDUINO】HC-05蓝牙不配对问题
除了刷主从之外,不配对的原因有1:已经配对其他设备,需用AT+RMAAD来移除.2.默认为蓝牙由绑定指令设置,需改为任意地址连接模式AT+CMODE=1 //#define AT 2 #define ...
- 进度条在.net导入Excel时的应用实例
这篇文章主要介绍了进度条在.net导入Excel时的应用,以实例形式讲述了.net导入Excel时根据页面情况显示进度条的实现方法,非常具有实用价值,需要的朋友可以参考下 本文实例讲述了进度条在.ne ...
- java-web 过滤器 & 监听器 & 拦截器
Tomcat 的容器分为四个等级.真正管理 Servlet 的容器是 Context 容器,一个 Context 对应一个 Web 工程.在 Tomcat 的配置文件里能够非常easy发现这一点.例如 ...
- Sort List[leetcode] 由归并排序的递归和循环,到本题的两种解法
归并排序能够有两种思路----top-down 和 bottom-up top-down: 递归实现,将数组分成两半.分别处理.再合并. 伪代码例如以下: split ( A[], l, r) { i ...
- js获取上个月的第一天和最后一天
var now = new Date(); var fd = new Date(now.getFullYear(), now.getMonth()-1 ,1).toLocaleDateString() ...
- 在Scrapy中使用IP池或用户代理更新版(python3)
middlewares.py # -*- coding: utf-8 -*- # 导入随机模块 import random # 导入有关IP池有关的模块 from scrapy.downloaderm ...
- mysql主从同步因断电产生的不能同步问题
偶尔因为断电导致mysql slave 出现复制错误“Could not parse relay log event entry” Could not parse relay log event en ...