采用代码的方式推流(javacv+ffmpeg-platform)

    科技2022-08-15  103

    装载于: https://blog.csdn.net/qq_40321119/article/details/108336324

    1.导入jar包

    <dependency> <groupId>org.bytedeco</groupId> <artifactId>javacv</artifactId> <version>1.5.1</version> </dependency> <dependency> <groupId>org.bytedeco</groupId> <artifactId>ffmpeg-platform</artifactId> <version>4.1.3-1.5.1</version> </dependency>

    2.代码实现

    import org.bytedeco.ffmpeg.avcodec.AVPacket; import org.bytedeco.ffmpeg.avformat.AVFormatContext; import org.bytedeco.javacv.FFmpegFrameGrabber; import org.bytedeco.javacv.FFmpegFrameRecorder; import java.io.IOException; import static org.bytedeco.ffmpeg.global.avcodec.av_free_packet; public class ConvertVideoPakcet { FFmpegFrameGrabber grabber = null; FFmpegFrameRecorder record = null; int width = -1, height = -1; // 视频参数 protected int audiocodecid; protected int codecid; protected double framerate;// 帧率 protected int bitrate;// 比特率 // 音频参数 // 想要录制音频,这三个参数必须有:audioChannels > 0 && audioBitrate > 0 && sampleRate > 0 private int audioChannels; private int audioBitrate; private int sampleRate; /** * 选择视频源 * @param src * @author eguid * @throws Exception */ public ConvertVideoPakcet from(String src) throws Exception { // 采集/抓取器 grabber = new FFmpegFrameGrabber(src); if(src.indexOf("rtsp")>=0) { grabber.setOption("rtsp_transport","tcp"); } grabber.start();// 开始之后ffmpeg会采集视频信息,之后就可以获取音视频信息 if (width < 0 || height < 0) { width = grabber.getImageWidth(); height = grabber.getImageHeight(); } // 视频参数 audiocodecid = grabber.getAudioCodec(); System.err.println("音频编码:" + audiocodecid); codecid = grabber.getVideoCodec(); framerate = grabber.getVideoFrameRate();// 帧率 bitrate = grabber.getVideoBitrate();// 比特率 // 音频参数 // 想要录制音频,这三个参数必须有:audioChannels > 0 && audioBitrate > 0 && sampleRate > 0 audioChannels = grabber.getAudioChannels(); audioBitrate = grabber.getAudioBitrate(); if (audioBitrate < 1) { audioBitrate = 128 * 1000;// 默认音频比特率 } return this; } /** * 选择输出 * @param out * @author eguid * @throws IOException */ public ConvertVideoPakcet to(String out) throws IOException { // 录制/推流器 record = new FFmpegFrameRecorder(out, width, height); record.setVideoOption("crf", "18"); record.setGopSize(2); record.setFrameRate(framerate); record.setVideoBitrate(bitrate); record.setAudioChannels(audioChannels); record.setAudioBitrate(audioBitrate); record.setSampleRate(sampleRate); AVFormatContext fc = null; if (out.indexOf("rtmp") >= 0 || out.indexOf("flv") > 0) { // 封装格式flv record.setFormat("flv"); record.setAudioCodecName("aac"); record.setVideoCodec(codecid); fc = grabber.getFormatContext(); } record.start(fc); return this; } /** * 转封装 * @author eguid * @throws IOException */ public ConvertVideoPakcet go() throws IOException { long err_index = 0;//采集或推流导致的错误次数 //连续五次没有采集到帧则认为视频采集结束,程序错误次数超过1次即中断程序 for(int no_frame_index=0;no_frame_index<5||err_index>1;) { AVPacket pkt=null; try { //没有解码的音视频帧 pkt=grabber.grabPacket(); if(pkt==null||pkt.size()<=0||pkt.data()==null) { //空包记录次数跳过 no_frame_index++; continue; } //不需要编码直接把音视频帧推出去 err_index+=(record.recordPacket(pkt)?0:1);//如果失败err_index自增1 System.out.println(err_index); av_free_packet(pkt); }catch (IOException e) {//推流失败 System.out.println("++++++++++++++++++++++++++++++++++++++++++"); err_index++; } catch (Exception e) { System.out.println("-------------------------------------------"); err_index++; } } return this; } public static void main(String[] args) throws Exception, IOException { //运行,设置视频源和推流地址 new ConvertVideoPakcet().from("<rtsp地址>") .to("rtmp://localhost:1935/mytv/test2") .go(); } }

    这是我自己改的,可能是因为配置问题 之前一直报 Exception in thread “main” org.bytedeco.javacv.FrameGrabber$Exception: avfor

    <dependency> <groupId>org.bytedeco.javacpp-presets</groupId> <artifactId>opencv-platform</artifactId> <version>3.4.1-1.4.1</version> </dependency> <dependency> <groupId>org.bytedeco</groupId> <artifactId>javacv</artifactId> <version>1.5.1</version> </dependency> <dependency> <groupId>org.bytedeco</groupId> <artifactId>ffmpeg-platform</artifactId> <version>4.1.3-1.5.1</version> </dependency>
    Processed: 0.020, SQL: 9