前言
最近准备写一个播放器,所有需要将视频文件进行编解码,目前只实现通过FFMPEG的API将视频码流抽取出来。后面准备音频文件抽取,然后进行重采样。
Maven依赖
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>javacv-platform</artifactId>
<version>1.5.1</version>
<exclusions>
<exclusion>
<groupId>org.bytedeco</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>ffmpeg-platform</artifactId>
<version>4.1.3-1.5.1</version>
</dependency>
代码实现
package com.xl.ffmpeg;
import org.bytedeco.ffmpeg.avcodec.*;
import org.bytedeco.ffmpeg.avformat.*;
import org.bytedeco.ffmpeg.avutil.*;
import static org.bytedeco.ffmpeg.global.avcodec.*;
import static org.bytedeco.ffmpeg.global.avformat.*;
import static org.bytedeco.ffmpeg.global.avutil.*;
public class Test1 {
public static void main(String[] args) {
AVFormatContext allFormatCtx=avformat_alloc_context();
String openUrl="./1.mp4";
String outputVideo="./video.mp4";
avformat_open_input(allFormatCtx,openUrl,null,null);
avformat_find_stream_info(allFormatCtx,(AVDictionary)null);
int videoStreamIndex=av_find_best_stream(allFormatCtx,AVMEDIA_TYPE_VIDEO,-1,-1,(AVCodec)null,0);
AVStream videoStream=allFormatCtx.streams(videoStreamIndex);
AVCodec videoCode=avcodec_find_decoder(videoStream.codecpar().codec_id());
AVOutputFormat videoOutFmt = av_guess_format(null,outputVideo,null);
AVFormatContext videoFmtOutCtx = avformat_alloc_context();
AVIOContext videoPd=new AVIOContext();
avformat_alloc_output_context2(videoFmtOutCtx,videoOutFmt,videoOutFmt.name().getString(),outputVideo);
AVStream outVideoStream = avformat_new_stream(videoFmtOutCtx,videoCode);
avcodec_parameters_copy(outVideoStream.codecpar(),videoStream.codecpar());
AVCodecContext videoCodecCtx=avcodec_alloc_context3(videoCode);
avcodec_parameters_to_context(videoCodecCtx, allFormatCtx.streams(videoStreamIndex).codecpar());
avcodec_open2(videoCodecCtx, videoCode, (AVDictionary)null);
avio_open(videoPd,outputVideo,AVIO_FLAG_READ_WRITE);
videoFmtOutCtx.pb(videoPd);
avformat_write_header(videoFmtOutCtx,(AVDictionary)null);
AVPacket pkt = av_packet_alloc();
av_init_packet(pkt);
while(av_read_frame(allFormatCtx,pkt)>=0){
pkt.pos(-1);
if(pkt.stream_index()==videoStreamIndex) {
pkt.stream_index(videoStream.index());
pkt.duration((int) av_rescale_q(pkt.duration(), videoStream.codec().time_base(), outVideoStream.codec().time_base()));
pkt.pts(av_rescale_q_rnd(pkt.pts(), videoStream.time_base(), outVideoStream.time_base(),(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX)));//Increase pts calculation
pkt.dts(av_rescale_q_rnd(pkt.dts(), videoStream.time_base(), outVideoStream.time_base(),(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX)));//Increase dts calculation
av_interleaved_write_frame(videoFmtOutCtx, pkt);
}
av_packet_unref(pkt);
}
//写入尾部信息
av_write_trailer(videoFmtOutCtx);
//释放资源,释放pkt
av_free(pkt);
//关闭aviocontext 写入完成
avio_close(videoFmtOutCtx.pb());
//释放ofmt_ctx
avformat_free_context(videoFmtOutCtx);
//关闭并释放输入ifmt_ctx
avformat_close_input(allFormatCtx);
}
}
网友评论