package com.gezk.service;
public class RecordVideo {
private FFmpegFrameGrabber grabber = null;
private FFmpegFrameRecorder recorder = null;
AVFormatContext fc;
int kuan=0;
int gao=0;
// 视频参数
/**
* 选择视频源
* @param src
* @author eguid
* @throws Exception
*/
public RecordVideo sourcesRtsp(String src) throws Exception {
// 采集/抓取器
Log.e("正在推送","src :"+src);
grabber = new FFmpegFrameGrabber(src);
avutil.av_log_set_level(avutil.AV_LOG_ERROR);
FFmpegLogCallback.set();
kuan=grabber.getImageWidth();
gao=grabber.getImageHeight();
Log.e("正在推送"," grabber : "+grabber);
grabber.start();// 开始之后ffmpeg会采集视频信息,之后就可以获取音视频信息
Log.e("正在推送","grabber : "+grabber);
return this;
}
/**
* 选择输出
* @param out
* @author eguid
* @throws IOException
*/
public RecordVideo target(String out) throws IOException {
// 流媒体输出地址,分辨率(长,高),是否录制音频(0:不录制/1:录制) ?overrun_nonfatal=1&fifo_size=50000000
//这里udp地址增加参数扩大udp缓存
Log.e("正在推送","out :"+out);
recorder = new FFmpegFrameRecorder(out, kuan,gao,0);
recorder.setGopSize(2);
recorder.setFrameRate(15);
recorder.setVideoBitrate(2000000);
Log.e("正在推送","recorder : "+recorder);
if (out.indexOf("rtmp") >= 0 || out.indexOf("flv") > 0) {
// Package format flv
recorder.setFormat("flv");
recorder.setAudioCodecName("aac");
fc = grabber.getFormatContext();
}
//在这一步报错了 报错内容为:avformat_write_header error() error -22: Could not write header to 'rtmp地址'
recorder.start(fc);
Log.e("正在推送","recorder11 : "+recorder);
return this;
}
/**
* 转封装
* @author eguid
* @throws IOException
*/
public RecordVideo go() throws IOException {
System.out.println("开始推送...");
long err_index = 0;//采集或推流导致的错误次数
// 释放探测时缓存下来的数据帧,避免pts初始值不为0导致画面延时
grabber.flush();
//错误采集判断
for(int no_frame_index = 0; no_frame_index < 10 || err_index > 1;) {
AVPacket pkt;
try {
pkt = grabber.grabPacket();
if(pkt == null || pkt.size() <= 0 || pkt.data() == null) {
//空包记录次数跳过
no_frame_index ++;
continue;
}
//不需要编码频帧推出去
err_index += (recorder.recordPacket(pkt) ? 0 : 1);//如果失败err_index自增1
Log.e("正在推送",""+err_index);
av_packet_unref(pkt);
} catch (IOException e) {//推流失败
err_index++;
}
}
return this;
}
}
这个代码我也是网上找的,之前没做过相关的内容,我网上查找的结果都是在说:是recorder.setFormat("flv");设置的格式不对,我这边确实是flv我之前通过frame方式推送成功过了。
现在这个执行到了recorder.start(fc);方法时就会报错,内容为:avformat_write_header error() error -22: Could not write header to 'rtmp地址'
另外我之前通过recorder.record(frame) 的方式推送的时候延迟非常严重,经常推送2分钟就有50或60秒左右的延迟。
如果转封装的方式不行的话,降低recorder.record(frame) 推送延迟也可以的,降低到大概5分钟10秒钟延迟这样
我找了好久的原因,实在是自己找不到办法了。