javacv_音视频基础操作

本文档介绍了一个使用JavaCV库在两天内完成的音视频转码和截取功能。通过引入javacv-platform Maven依赖,实现了从输入文件中抓取帧,然后将帧记录到新的MP4文件中,转换过程包括设置输出路径、帧率、视频编码等参数。代码中包含了性能测试,并记录了转换所需时间和文件大小。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

因为工作需要,这边花了2天时间 做了一个基于javacv进行音视频转码,以及音视频截取功能,已经进行部分压测,没有问题。本文章是参考网上的方案,但是原来的链接没有记录。如果原作者发现了,可以私聊我,或者直接在下方评论把链接粘贴。本帖只发视频转码部分

# maven依赖
<dependency>
	<groupId>org.bytedeco</groupId>
	<artifactId>javacv-platform</artifactId>
	<version>1.5.3</version>
</dependency>

大致流程:

image-20220107164837786

import org.bytedeco.ffmpeg.global.avcodec;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.FFmpegFrameRecorder;
import org.bytedeco.javacv.Frame;
import org.bytedeco.javacv.FrameGrabber;
import org.springframework.util.StopWatch
    
public long convert2mp4(File file, String videoSavePath) throws IOException {
        // 判断文件夹存在
        File saveVideoPath = new File(videoSavePath);
        if (!saveVideoPath.exists() && !saveVideoPath.isDirectory()) {
            saveVideoPath.mkdirs();
        }

        //第一步:设置输出的文件路径
        String csvname = videoSavePath + File.separator + file.getAbsolutePath().substring(file.getAbsolutePath().lastIndexOf(File.separator) + 1) + ".csv";
        //如果该目录下不存在该文件,则文件会被创建到指定目录下。如果该目录有同名文件,那么该文件将被覆盖。
        File writeFile = new File(csvname);
        //第二步:通过BufferedReader类创建一个使用默认大小输出缓冲区的缓冲字符输出流
        BufferedWriter writeText = new BufferedWriter(new FileWriter(writeFile));


        //创建并启动StopWatch
        StopWatch stopwatch = new StopWatch();
        stopwatch.start();
        FFmpegFrameGrabber frameGrabber = new FFmpegFrameGrabber(file.getAbsolutePath());
        String fileFullPathName = null;

        Frame captured_frame = null;

        FFmpegFrameRecorder recorder = null;

        try {
            frameGrabber.start();
            //获取转换后的文件名
            String filename = file.getName().substring(0, file.getName().lastIndexOf(".")) + "_" + file.getName().substring(file.getName().lastIndexOf(".") + 1) + ".mp4";
            //更换转码后视频存储位置
            fileFullPathName = videoSavePath + File.separator + filename;

            recorder = new FFmpegFrameRecorder(fileFullPathName, frameGrabber.getImageWidth(), frameGrabber.getImageHeight(), frameGrabber.getAudioChannels());
            recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
            recorder.setFormat("mp4");
            recorder.setFrameRate(frameGrabber.getFrameRate());
            recorder.setVideoBitrate(frameGrabber.getVideoBitrate());
            recorder.setAudioBitrate(192000);
            recorder.setAudioOptions(frameGrabber.getAudioOptions());
            recorder.setAudioQuality(0);
            recorder.setSampleRate(44100);
            recorder.setAudioCodec(avcodec.AV_CODEC_ID_AAC);
            recorder.start();
            while (true) {
                try {
                    captured_frame = frameGrabber.grabFrame();

                    if (captured_frame == null) {
                        System.out.println("\n\nfinish  " + fileFullPathName+"\n\n");
                        break;
                    }
                    recorder.record(captured_frame);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            recorder.stop();
            recorder.release();
            frameGrabber.stop();
            frameGrabber.release();
            recorder.close();
            frameGrabber.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        stopwatch.stop();
        writeText.newLine();    //换行
        //调用write的方法将字符串写到流中
        writeText.write(fileFullPathName +","+ stopwatch.getLastTaskTimeMillis()/1000 +"s," + (float) new FileInputStream(fileFullPathName).getChannel().size() / 1024 / 1024+"MB");
        //使用缓冲区的刷新方法将数据刷到目的地中
        writeText.flush();
        //关闭缓冲区,缓冲区没有调用系统底层资源,真正调用底层资源的是FileWriter对象,缓冲区仅仅是一个提高效率的作用
        //因此,此处的close()方法关闭的是被缓存的流对象
        writeText.close();
        return stopwatch.getLastTaskTimeMillis()/1000;
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kui9702

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值