美文网首页
JAVA通过FFMPEG实现视频抽取

JAVA通过FFMPEG实现视频抽取

作者: 何亮hook_8285 | 来源:发表于2021-11-01 00:38 被阅读0次

前言

最近准备写一个播放器,所有需要将视频文件进行编解码,目前只实现通过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);


    }


}

相关文章

网友评论

      本文标题:JAVA通过FFMPEG实现视频抽取

      本文链接:https://www.haomeiwen.com/subject/hyoaaltx.html