ffmpeg视频转码相关

news2025/4/16 21:49:55

ffmpeg视频转码相关

  • 简介
    • 参数
  • 实战举栗子
    • 获取视频时长
    • 视频转码
    • mp4文件转为hls m3u8 ts等文件
    • 图片转视频
    • 抽取视频第一帧
    • 获取基本信息
  • 转码日志输出详解
  • 转码耗时测试

简介

FFmpeg 是领先的多媒体框架,能够解码、编码、 转码、复用、解复用、流、过滤和播放 几乎所有人类和机器创建的东西。

ffmpeg官网: https://ffmpeg.org/
ffmpeg中文网: https://ffmpeg.p2hp.com/

参数


  1. 基本操作
    输入文件
    -i input.mp4:指定输入文件。

    输出文件
    output.mp4:指定输出文件名称。


  1. 视频参数
    设置分辨率
    -s 1280x720:设置输出视频的分辨率(宽x高)。

    设置帧率
    -r 24:设置输出视频的帧率(帧每秒,FPS)。

    设置视频码率
    -b:v 2000k:设置视频码率(比特率)。

    设置GOP大小
    -g 48:设置GOP(组图像)大小,通常与帧率相关。

    设置封面
    -ss 00:00:01:从指定时间点截取一帧作为封面(配合 -vframes 1 使用)。


  1. 音频参数
    设置音频码率
    -b:a 128k:设置音频码率。

    设置采样率
    -ar 44100:设置音频采样率。

    选择音频通道
    -ac 2:设置音频通道数(如立体声为2)。


  1. 格式转换
    指定输出格式
    -f mp4:强制指定输出格式。

  1. 截图和分片
    截图
    -ss 00:00:05 -vframes 1 output.jpg:从第5秒时间点截取一帧并保存为图片。

    分片输出
    -f segment -segment_time 10 -c copy output%03d.mp4:将视频每10秒切成一个分片。


  1. 音视频同步
    同步音视频
    -async 1:在流式传输中同步音视频。

    声音延迟
    -itsoffset 0.5 -i input.mp4:调整声音与视频的同步(+延迟/-提前)。


  1. 旋转或翻转视频
    旋转video
    -vf “rotate=90”:旋转视频90度(支持0,90,180,270度)。

    水平翻转
    -vf “hflip”:水平翻转视频。

    垂直翻转
    -vf “vflip”:垂直翻转视频。


  1. 过滤器
    ffmpeg 支持复杂的过滤器链,例如:

    添加水印
    -i watermark.png -filter_complex “overlay=W-w:0” output.mp4:在视频右下角添加水印。

    画中画
    -i small.mp4 -filter_complex “overlay=main_w/2:main_h/2” output.mp4:在视频中插入另外一个小视频。


  1. 编码器
    指定视频编码器
    -c:v h264:使用H.264编码器。

    指定音频编码器
    -c:a aac:使用AAC音频编码器。


  1. 时间控制
    播放速度
    -vf “setpts=2*PTS”:将视频速度加快2倍。

    剪辑视频
    -ss 00:01:00 -t 00:01:00 -c copy output.mp4:从第1分钟开始剪辑1分钟的视频。

    提取音频
    -vn -ar 44100 -ac 2 -ab 128k output.mp3:提取视频中的音频并保存为MP3。

    生成静音
    -f lavfi -i anullsrc -c:a aac output.mka:生成一个没有视频的静音文件。


  1. 压缩和质量
    CRF(质量控制)
    -crf 18:设置视频质量(18-28,数值越小质量越高)。

    预设
    -preset ultrafast:设置编码速度(如:ultrafast, superfast, veryfast, faster, fast, medium)。


示例

将 MP4 转换为 H.264 编码的 MKV:

ffmpeg -i input.mp4 -c:v h264 output.mkv

将视频压缩到1Mbps:

ffmpeg -i input.mp4 -c:v h264 -b:v 1000k output.mp4

提取视频的音频:

ffmpeg -i input.mp4 -vn -ar 44100 -ac 2 -ab 128k output.mp3

将视频旋转90度:

ffmpeg -i input.mp4 -vf “rotate=90” output.mp4

实战举栗子

获取视频时长

//    Duration: 00:00:30.03, start: 0.000000, bitrate: 1191 kb/s
    public String getVideoDuration(String inputFilePath) {
        Process process = null;
        try {
            // 定义远程视频的URL
            // 构建FFmpeg命令
            ProcessBuilder processBuilder = new ProcessBuilder(ffmpegPath, "-i",inputFilePath);
            // 读取FFmpeg的输出信息
            // 创建ProcessBuilder并执行命令
            processBuilder.redirectErrorStream(true);
            process = processBuilder.start();
            // 读取FFmpeg命令输出
            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String line;
            while ((line = reader.readLine()) != null) {
                if (line.contains("Duration:")) {
                    // 获取包含视频时长信息的行
                    String durationLine = line.split("Duration:")[1].split(",")[0].split("\\.")[0].trim();// 00:00:30
//                    String durationLine = line.split("Duration:")[1].split(",")[0].trim();// 00:00:30.03
//                    String[] durationParts = durationLine.split(":");
//                    int hours = Integer.parseInt(durationParts[0].trim());
//                    int minutes = Integer.parseInt(durationParts[1].trim());
//                    double seconds = Double.parseDouble(durationParts[2].trim());
//                    // 计算总秒数
//                    double totalSeconds = hours * 3600 + minutes * 60 + seconds;
                    System.out.println("视频时长:" + durationLine);
                    return durationLine;
                }
            }
            reader.close();
        } catch (IOException e) {
            e.printStackTrace();
            if (process != null) {
                process.destroyForcibly();  // 如果发生异常,强制终止进程
            }
        } finally {
            if (process != null) {
                process.destroyForcibly();  // 强制终止进程
            }
        }
        System.out.println("无法获取视频时长。");
        return null;
    }

	public Integer getVideoDurationSecond(String inputFilePath) {
        String videoDuration = getVideoDuration(inputFilePath);
        if (videoDuration == null) {
            return 0;
        }
        String[] durationParts = videoDuration.split(":");
        int hours = Integer.parseInt(durationParts[0].trim());
        int minutes = Integer.parseInt(durationParts[1].trim());
        int seconds = Integer.parseInt(durationParts[2].trim());
        // 计算总秒数
        return hours * 3600 + minutes * 60 + seconds;
    }

视频转码

	public void transcodeVideo(String inputFilePath, String outputFilePath) {
        ProcessBuilder processBuilder = new ProcessBuilder(ffmpegPath, "-i",inputFilePath, "-c:v", "libx264", "-c:a", "aac", outputFilePath);
        try {
            processBuilder.inheritIO(); // 将FFmpeg的输出信息打印到控制台
//            processBuilder.redirectErrorStream(true); // 合并错误输出流
            Process process = processBuilder.start();

            int exitCode = process.waitFor();
            if (exitCode == 0) {
                log.info("视频转码成功!");
            } else {
                log.info("视频转码失败!");
            }
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
    }

mp4文件转为hls m3u8 ts等文件

public void convertMp4ToM3u8(String inputFilePath, String outputDirectory, String defineOutputFileName) {
        File inputFile = new File(inputFilePath);
        if (!inputFile.exists()) {
            throw new IllegalArgumentException("Input file not found: " + inputFilePath);
        }

        File outputDir = new File(outputDirectory);
        if (!outputDir.exists()) {
            outputDir.mkdirs();
        }

        // Output filename without extension
        String outputFileName = inputFile.getName().replaceFirst("[.][^.]+$", "");
        if (StringUtils.isNotBlank(defineOutputFileName)) {// 自定义名称
            outputFileName = defineOutputFileName;
        }

        Process process = null;
        try {
            // Command to convert MP4 to M3U8 using FFmpeg
            List<String> command = new ArrayList<>();
            command.add(ffmpegPath);
            command.add("-i");
            command.add(inputFilePath);
            command.add("-c:v");
            command.add("libx264");
            command.add("-hls_time");
            command.add("10"); // 设置每个分片的时长,单位为秒
            command.add("-hls_list_size");
            command.add("0");
            command.add("-hls_segment_filename");
            command.add(outputDirectory + "/" + outputFileName + "_%03d.ts");
            command.add(outputDirectory + "/" + outputFileName + ".m3u8");

            ProcessBuilder pb = new ProcessBuilder(command);
            pb.inheritIO(); // 将FFmpeg的输出信息打印到控制台
            process = pb.start();
            int exitCode = process.waitFor();
            if (exitCode == 0) {
                log.info("视频转换成功!");
            } else {
                log.info("视频转换失败!");
            }
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
            if (process != null) {
                process.destroyForcibly();  // 如果发生异常,强制终止进程
            }
        } finally {
            if (process != null) {
                process.destroyForcibly();  // 如果发生异常,强制终止进程
            }
        }

        // Check if the conversion was successful
        File m3u8File = new File(outputDirectory + "/" + outputFileName + ".m3u8");
        if (!m3u8File.exists()) {
            throw new RuntimeException("M3U8 file was not generated");
        }
    }

图片转视频

/**
     * 图片转为视频
     * E://yla-tool//ffmpeg//ffmpeg-7.0.1-full_build//bin//ffmpeg.exe -framerate 0.2 -f image2 -i 素材%d.png -vf scale=1920:1080  -c:v libx264 -profile:v high  -crf 20 -pix_fmt yuv420p test.mp4
     * E://yla-tool//ffmpeg//ffmpeg-7.0.1-full_build//bin//ffmpeg.exe -r 15 -loop 1 -i 01.jpg -vf scale=1920:1080 -c:v libx264 -profile:v high -crf 20 -pix_fmt yuv420p -t 10 -r 15 111.mp4
     * 暂不支持多张图片
     * @param imagePaths
     * @param outputVideoPath
     * @param r 帧率
     * @param t 时长
     */
    public Integer generateVideo (List<String> imagePaths, String outputVideoPath, int r, int t) {
//        StringBuilder ffmpegCommand = new StringBuilder(ffmpegPath + " -framerate ");
//        ffmpegCommand.append(fps).append(" -i ");// 设置帧率和输入格式

        StringBuilder ffmpegCommand = new StringBuilder(ffmpegPath);
        ffmpegCommand.append(" -r ");
        ffmpegCommand.append(r);
        ffmpegCommand.append(" -loop 1 ");
        ffmpegCommand.append(" -i ");// 设置帧率和输入格式

        for (String imagePath : imagePaths) {
            ffmpegCommand.append(imagePath).append(" ");// 添加每个图片的路径
        }
        ffmpegCommand.append("-vf scale=1920:1080 -c:v libx264 -profile:v high -crf 20 -pix_fmt yuv420p ")// 设置视频编码和质量
                .append(" -t ")
                .append(t)
                .append(" -r ")
                .append(r)
                .append(" ")
                .append(outputVideoPath);// 设置视频输出路径

        Process process = null;
        try {
            process = Runtime.getRuntime().exec(ffmpegCommand.toString());
            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
            }

            reader.close();
            int exitCode = process.waitFor();
            if (exitCode == 0) {
                log.info("视频生成成功,路径:" + outputVideoPath);
            } else {
                log.info("视频生成失败!");
            }
            return exitCode;
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
            if (process != null) {
                process.destroyForcibly();  // 如果发生异常,强制终止进程
            }
        } finally {
            if (process != null) {
                process.destroyForcibly();  // 如果发生异常,强制终止进程
            }
        }
        return null;
    }

抽取视频第一帧

public void previewVideo (HttpServletResponse response, String videoPath) {
//        String videoPath = "path/to/your/video/sample.mp4"; // 替换为你的视频文件路径
//        int startTimeSeconds = 0; // 开始时间,单位为秒
//        int durationSeconds = 5; // 需要提取的视频时长,单位为秒
        int frameTime = 0; // 提取第一帧图像的时间,单位为秒  (原取1 但是1秒钟的视频 抽帧图片缺失故改为0)
//
//        try {
//            // 构建 FFmpeg 命令
//            String ffmpegCmd = String.format(ffmpegPath + " -ss %d -i %s -t %d -f image2pipe -vcodec mjpeg -", startTimeSeconds, videoPath, durationSeconds);

        Process process = null;
        try {
            // 构建 FFmpeg 命令
//            String ffmpegCmd = String.format(ffmpegPath + " -ss %d -i %s -frames:v 1 -f image2pipe -vcodec mjpeg -", frameTime, videoPath);
            String imagePath = fileDir + "temp_image_" + UUID.randomUUID() + ".jpg";
            System.out.println(imagePath);
//            -ss 0 -i input.mp4 -frames:v 1 -f image2 output.jpg
//            String ffmpegCmd = String.format(" -ss %d -i %s -frames:v 1 -f image2 %s", frameTime, videoPath, imagePath);
//            process = Runtime.getRuntime().exec(ffmpegCmd);
            ProcessBuilder processBuilder = new ProcessBuilder(ffmpegPath,
                    "-ss", frameTime+"",
                    "-i", videoPath,
                    "-frames:v", "1",
                    "-q:v", "30",
                    imagePath
                    );
            processBuilder.inheritIO(); // 将FFmpeg的输出信息打印到控制台
            process = processBuilder.start();

            int exitCode = process.waitFor();
            if (exitCode == 0) {
                log.info("抽取第一帧成功!");
            } else {
                log.info("抽取第一帧失败!");
            }

            // 读取生成的图片
            InputStream inputStream = new FileInputStream(imagePath);

            // 设置响应头
            response.setContentType("image/jpeg");
            OutputStream outputStream = response.getOutputStream();

            // 从 FFmpeg 输出流读取数据并写入到 Servlet 输出流
            byte[] buffer = new byte[1024];
            int bytesRead;
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
            }

            outputStream.flush();
            outputStream.close();
            inputStream.close();

            // 删除临时图片文件
            Files.delete(Paths.get(imagePath));

        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
            if (process != null) {
                process.destroyForcibly();  // 如果发生异常,强制终止进程
            }
            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        } finally {
            if (process != null) {
                process.destroyForcibly();  // 如果发生异常,强制终止进程
            }
        }
    }

获取基本信息

package net.yla.board.core.utils;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;

public class VideoConverter {
    public static void main(String[] args) {
//        "-c:v", "libx264", "-b:v", "4027k", "-preset", "ultrafast", "-threads", "4", "-c:a", "aac",

//        String inputVideo = "E:\\testm3u8\\西藏2.mp4";
        String inputVideo = "E:\\图片夹\\视频雪景.mp4";
        String outputPlaylist = "E:\\testm3u8\\output.m3u8";
        long l1 = System.currentTimeMillis();
//        ProcessBuilder processBuilder = new ProcessBuilder("E:\\yla-tool\\ffmpeg\\ffmpeg-7.0.1-full_build\\bin\\ffmpeg.exe", "-i",inputVideo);

//        E:\\yla-tool\\ffmpeg\\ffmpeg-7.0.1-full_build\\bin\\ffmpeg.exe -i E:\图片夹\公司宣传.mp4 -c:v libx264 -hls_time 10 -hls_list_size 0 -f hls -hls_segment_filename E:\\图片夹\\output%03d.ts E:\图片夹\output.m3u8
//        ProcessBuilder processBuilder = new ProcessBuilder("E:\\yla-tool\\ffmpeg\\ffmpeg-7.0.1-full_build\\bin\\ffmpeg.exe", "-i", inputVideo, "-c:v", "libx264", "-hls_time", "10", "-hls_list_size", "0", "-f", "hls", "-hls_segment_filename", "E:\\testm3u8\\" + "output%03d.ts", outputPlaylist);
        ProcessBuilder processBuilder = new ProcessBuilder("E:\\yla-tool\\ffmpeg\\ffmpeg-7.0.1-full_build\\bin\\ffmpeg.exe", "-i",inputVideo);
//        ProcessBuilder processBuilder = new ProcessBuilder("E:\\yla-tool\\ffmpeg\\ffmpeg-7.0.1-full_build\\bin\\ffmpeg.exe", "-i",inputVideo, "-c:v", "libx264", "-b:v", "4000k", "-preset", "ultrafast",  "-c:a", "aac", System.currentTimeMillis() + ".mp4");
        try {
            processBuilder.inheritIO(); // 将FFmpeg的输出信息打印到控制台
//            processBuilder.redirectErrorStream(true); // 合并错误输出流
            Process process = processBuilder.start();

//            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
//            String line;
//
//            while ((line = reader.readLine()) != null) {
//                System.out.println(line); // 打印FFmpeg输出的每一行
//                // 解析进度信息
//                if (line.contains("frame=")) {
//                    String[] parts = line.split(" ");
//                    for (String part : parts) {
//                        if (part.startsWith("time=")) {
//                            String time = part.split("=")[1];
//                            System.out.println("Current Time: " + time);
//                        }
//                    }
//                }
//            }

            int exitCode = process.waitFor();
            if (exitCode == 0) {
                System.out.println("视频转换成功!");
                System.out.println("转换耗时:" + (System.currentTimeMillis() - l1) / 1000 + "秒");
            } else {
                System.out.println("视频转换失败!");
            }
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
    }
}

基本信息打印结果如下

ffmpeg version 7.0.1-full_build-www.gyan.dev Copyright (c) 2000-2024 the FFmpeg developers
  built with gcc 13.2.0 (Rev5, Built by MSYS2 project)
  configuration: --enable-gpl --enable-version3 --enable-static --disable-w32threads --disable-autodetect --enable-fontconfig --enable-iconv --enable-gnutls --enable-libxml2 --enable-gmp --enable-bzlib --enable-lzma --enable-libsnappy --enable-zlib --enable-librist --enable-libsrt --enable-libssh --enable-libzmq --enable-avisynth --enable-libbluray --enable-libcaca --enable-sdl2 --enable-libaribb24 --enable-libaribcaption --enable-libdav1d --enable-libdavs2 --enable-libuavs3d --enable-libxevd --enable-libzvbi --enable-librav1e --enable-libsvtav1 --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxavs2 --enable-libxeve --enable-libxvid --enable-libaom --enable-libjxl --enable-libopenjpeg --enable-libvpx --enable-mediafoundation --enable-libass --enable-frei0r --enable-libfreetype --enable-libfribidi --enable-libharfbuzz --enable-liblensfun --enable-libvidstab --enable-libvmaf --enable-libzimg --enable-amf --enable-cuda-llvm --enable-cuvid --enable-dxva2 --enable-d3d11va --enable-d3d12va --enable-ffnvcodec --enable-libvpl --enable-nvdec --enable-nvenc --enable-vaapi --enable-libshaderc --enable-vulkan --enable-libplacebo --enable-opencl --enable-libcdio --enable-libgme --enable-libmodplug --enable-libopenmpt --enable-libopencore-amrwb --enable-libmp3lame --enable-libshine --enable-libtheora --enable-libtwolame --enable-libvo-amrwbenc --enable-libcodec2 --enable-libilbc --enable-libgsm --enable-libopencore-amrnb --enable-libopus --enable-libspeex --enable-libvorbis --enable-ladspa --enable-libbs2b --enable-libflite --enable-libmysofa --enable-librubberband --enable-libsoxr --enable-chromaprint
  libavutil      59.  8.100 / 59.  8.100
  libavcodec     61.  3.100 / 61.  3.100
  libavformat    61.  1.100 / 61.  1.100
  libavdevice    61.  1.100 / 61.  1.100
  libavfilter    10.  1.100 / 10.  1.100
  libswscale      8.  1.100 /  8.  1.100
  libswresample   5.  1.100 /  5.  1.100
  libpostproc    58.  1.100 / 58.  1.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'E:\图片夹\视频雪景.mp4':
  Metadata:
    major_brand     : mp42
    minor_version   : 0
    compatible_brands: mp42isomavc1
    creation_time   : 2023-11-24T11:51:45.000000Z
  Duration: 00:00:07.64, start: 0.000000, bitrate: 26320 kb/s
  Stream #0:0[0x1](und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709, progressive), 3840x2160, 26340 kb/s, 59.94 fps, 59.94 tbr, 60k tbn (default)
      Metadata:
        creation_time   : 2023-11-24T11:51:45.000000Z
        handler_name    : Vimeo Artax Video Handler
        vendor_id       : [0][0][0][0]
        encoder         : AVC Coding
  Stream #0:1[0x2](und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 189 kb/s (default)
      Metadata:
        creation_time   : 2023-11-24T11:51:45.000000Z
        handler_name    : Vimeo Artax Audio Handler
        vendor_id       : [0][0][0][0]
At least one output file must be specified

转码日志输出详解

输出内容如下:

视频码率:23604
ffmpeg version 7.0.1-full_build-www.gyan.dev Copyright (c) 2000-2024 the FFmpeg developers
  built with gcc 13.2.0 (Rev5, Built by MSYS2 project)
  configuration: --enable-gpl --enable-version3 --enable-static --disable-w32threads --disable-autodetect --enable-fontconfig --enable-iconv --enable-gnutls --enable-libxml2 --enable-gmp --enable-bzlib --enable-lzma --enable-libsnappy --enable-zlib --enable-librist --enable-libsrt --enable-libssh --enable-libzmq --enable-avisynth --enable-libbluray --enable-libcaca --enable-sdl2 --enable-libaribb24 --enable-libaribcaption --enable-libdav1d --enable-libdavs2 --enable-libuavs3d --enable-libxevd --enable-libzvbi --enable-librav1e --enable-libsvtav1 --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxavs2 --enable-libxeve --enable-libxvid --enable-libaom --enable-libjxl --enable-libopenjpeg --enable-libvpx --enable-mediafoundation --enable-libass --enable-frei0r --enable-libfreetype --enable-libfribidi --enable-libharfbuzz --enable-liblensfun --enable-libvidstab --enable-libvmaf --enable-libzimg --enable-amf --enable-cuda-llvm --enable-cuvid --enable-dxva2 --enable-d3d11va --enable-d3d12va --enable-ffnvcodec --enable-libvpl --enable-nvdec --enable-nvenc --enable-vaapi --enable-libshaderc --enable-vulkan --enable-libplacebo --enable-opencl --enable-libcdio --enable-libgme --enable-libmodplug --enable-libopenmpt --enable-libopencore-amrwb --enable-libmp3lame --enable-libshine --enable-libtheora --enable-libtwolame --enable-libvo-amrwbenc --enable-libcodec2 --enable-libilbc --enable-libgsm --enable-libopencore-amrnb --enable-libopus --enable-libspeex --enable-libvorbis --enable-ladspa --enable-libbs2b --enable-libflite --enable-libmysofa --enable-librubberband --enable-libsoxr --enable-chromaprint
  libavutil      59.  8.100 / 59.  8.100
  libavcodec     61.  3.100 / 61.  3.100
  libavformat    61.  1.100 / 61.  1.100
  libavdevice    61.  1.100 / 61.  1.100
  libavfilter    10.  1.100 / 10.  1.100
  libswscale      8.  1.100 /  8.  1.100
  libswresample   5.  1.100 /  5.  1.100
  libpostproc    58.  1.100 / 58.  1.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'E:\图片夹\视频-GreatWall.mp4':
  Metadata:
    major_brand     : mp42
    minor_version   : 0
    compatible_brands: mp42isomavc1
    creation_time   : 2024-02-04T21:36:53.000000Z
  Duration: 00:00:48.73, start: 0.000000, bitrate: 23604 kb/s
  Stream #0:0[0x1](und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709, progressive), 3840x2160, 23601 kb/s, 30 fps, 30 tbr, 30 tbn (default)
      Metadata:
        creation_time   : 2024-02-04T21:36:53.000000Z
        handler_name    : Vimeo Artax Video Handler
        vendor_id       : [0][0][0][0]
        encoder         : AVC Coding
Stream mapping:
  Stream #0:0 -> #0:0 (h264 (native) -> h264 (libx264))
Press [q] to stop, [?] for help
[libx264 @ 000001e505081300] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX FMA3 BMI2 AVX2
[libx264 @ 000001e505081300] profile Constrained Baseline, level 5.1, 4:2:0, 8-bit
[libx264 @ 000001e505081300] 264 - core 164 r3191 4613ac3 - H.264/MPEG-4 AVC codec - Copyleft 2003-2024 - http://www.videolan.org/x264.html - options: cabac=0 ref=1 deblock=0:0:0 analyse=0:0 me=dia subme=0 psy=1 psy_rd=1.00:0.00 mixed_ref=0 me_range=16 chroma_me=1 trellis=0 8x8dct=0 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=0 threads=9 lookahead_threads=1 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=0 weightp=0 keyint=250 keyint_min=25 scenecut=0 intra_refresh=0 rc=abr mbtree=0 bitrate=23604 ratetol=1.0 qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1.40 aq=0
Output #0, mp4, to '1744097594286.mp4':
  Metadata:
    major_brand     : mp42
    minor_version   : 0
    compatible_brands: mp42isomavc1
    encoder         : Lavf61.1.100
  Stream #0:0(und): Video: h264 (avc1 / 0x31637661), yuv420p(tv, bt709, progressive), 3840x2160, q=2-31, 23604 kb/s, 30 fps, 15360 tbn (default)
      Metadata:
        creation_time   : 2024-02-04T21:36:53.000000Z
        handler_name    : Vimeo Artax Video Handler
        vendor_id       : [0][0][0][0]
        encoder         : Lavc61.3.100 libx264
      Side data:
        cpb: bitrate max/min/avg: 0/0/23604000 buffer size: 0 vbv_delay: N/A
[out#0/mp4 @ 000001e5043e8100] video:140862KiB audio:0KiB subtitle:0KiB other streams:0KiB global headers:0KiB muxing overhead: 0.005820%
frame= 1462 fps= 80 q=-1.0 Lsize=  140870KiB time=00:00:48.73 bitrate=23680.1kbits/s speed=2.68x    
[libx264 @ 000001e505081300] frame I:6     Avg QP:29.67  size:814006
[libx264 @ 000001e505081300] frame P:1456  Avg QP:32.41  size: 95713
[libx264 @ 000001e505081300] mb I  I16..4: 100.0%  0.0%  0.0%
[libx264 @ 000001e505081300] mb P  I16..4:  1.3%  0.0%  0.0%  P16..4: 51.9%  0.0%  0.0%  0.0%  0.0%    skip:46.8%
[libx264 @ 000001e505081300] final ratefactor: 29.74
[libx264 @ 000001e505081300] coded y,uvDC,uvAC intra: 41.9% 22.8% 1.1% inter: 19.3% 5.8% 0.0%
[libx264 @ 000001e505081300] i16 v,h,dc,p: 23% 26% 35% 16%
[libx264 @ 000001e505081300] i8c dc,h,v,p: 53% 24% 14%  8%
[libx264 @ 000001e505081300] kb/s:23678.63
视频转换成功!
转换耗时:19

以下是对这段FFmpeg日志的逐行解释


  1. FFmpeg版本信息
    ffmpeg version 7.0.1-full_build-www.gyan.dev Copyright © 2000-2024 the FFmpeg developers
    built with gcc 13.2.0 (Rev5, Built by MSYS2 project)
    这是FFmpeg的版本信息,显示当前使用的是 FFmpeg 7.0.1。 -©©opyright信息表明FFmpeg是一个开源软件,由全球开发者社区维护。
    编译信息:使用了 gcc 13.2.0 编译,通过MSYS2项目构建。

  1. 配置信息
    configuration: --enable-gpl --enable-version3 --enable-static --disable-w32threads […] --enable-libx264 --enable-libx265 […]
    这是FFmpeg的配置选项,表示在编译时启用了某些功能:
    –enable-gpl:启用GPL(GNU通用公共许可证)许可协议。
    –enable-version3:启用GPL第三版协议。
    –enable-static:编译为静态库,而不是动态库。
    –enable-libx264 和 --enable-libx265:启用H.264(x264)和H.265(x265)编码支持。
    […] 表示省略了其他配置选项。

  1. FFmpeg核心库版本
    libavutil 59. 8.100 / 59. 8.100
    libavcodec 61. 3.100 / 61. 3.100
    libavformat 61. 1.100 / 61. 1.100
    libavdevice 61. 1.100 / 61. 1.100
    libavfilter 10. 1.100 / 10. 1.100
    libswscale 8. 1.100 / 8. 1.100
    libswresample 5. 1.100 / 5. 1.100
    libpostproc 58. 1.100 / 58. 1.100
    这些是FFmpeg的核心库版本信息,分别对应:
    libavutil:实用函数库。
    libavcodec:音视频编解码器库。
    libavformat:音视频格式处理库。
    libavdevice:输入/输出设备处理库。
    libavfilter:音视频滤镜库。
    libswscale:视频缩放和格式转换库。
    libswresample:音频重采样库。
    libpostproc:视频后处理库。

  1. 输入文件信息
    Input #0, mov,mp4,m4a,3gp,3g2,mj2, from ‘E:\图片夹\视频-GreatWall.mp4’:
    Metadata:
    major_brand : mp42
    minor_version : 0
    compatible_brands: mp42isomavc1
    creation_time : 2024-02-04T21:36:53.000000Z
    Duration: 00:00:48.73, start: 0.000000, bitrate: 23604 kb/s
    Stream #0:00x1: Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709, progressive), 3840x2160, 23601 kb/s, 30 fps, 30 tbr, 30 tbn (default)
    Metadata:
    creation_time : 2024-02-04T21:36:53.000000Z
    handler_name : Vimeo Artax Video Handler
    vendor_id : [0][0][0][0]
    encoder : AVC Coding
    输入文件路径:E:\图片夹\视频-GreatWall.mp4。
    文件Metadata:
    major_brand:主要品牌标识为 mp42。
    minor_version:次要版本号为 0。
    compatible_brands:兼容的品牌标识,包括 mp42 和 isom。
    creation_time:文件创建时间为 2024-02-04T21:36:53Z。
    流媒体信息:
    Stream #0:0 是输入文件的视频流。
    编码格式:H.264 (High)。
    分辨率:3840x2160(4K)。
    比特率:23601 kb/s。
    帧率:30 fps。
    色彩空间:yuv420p,适用于电视(tv),颜色空间为 bt709。
    Metadata:
    handler_name:处理器名称为 Vimeo Artax Video Handler。
    vendor_id:供应商ID为空。
    encoder:编码器为 AVC Coding。

  1. 流映射
    Stream mapping:
    Stream #0:0 -> #0:0 (h264 (native) -> h264 (libx264))
    流映射:指明输入的流如何映射到输出。
    Stream #0:0:输入的视频流(H.264)。
    输出的流:h264 (libx264),即使用 libx264 编码器重新编码。

  1. 按键提示
    Press [q] to stop, [?] for help
    提示用户可以按 q 停止转码过程,或按 ? 查看帮助信息。

  1. 视频编码器信息
    [libx264 @ 000001e505081300] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX FMA3 BMI2 AVX2
    [libx264 @ 000001e505081300] profile Constrained Baseline, level 5.1, 4:2:0, 8-bit
    [libx264 @ 000001e505081300] 264 - core 164 r3191 4613ac3 - H.264/MPEG-4 AVC codec - Copyleft 2003-2024 - http://www.videolan.org/x264.html - options: cabac=0 ref=1 deblock=0:0:0 analyse=0:0 me=dia subme=0 psy=1 psy_rd=1.00:0.00 mixed_ref=0 me_range=16 chroma_me=1 trellis=0 8x8dct=0 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=0 threads=9 lookahead_threads=1 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=0 weightp=0 keyint=250 keyint_min=25 scenecut=0 intra_refresh=0 rc=abr mbtree=0 bitrate=23604 ratetol=1.0 qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1.40 aq=0
    libx264:H.264编码器的详细信息。
    CPU支持:列出了CPU支持的指令集(如AVX、AVX2等)。
    Profile:使用的 profiles 是 Constrained Baseline,适用于移动设备和网页播放。
    Level:视频编码级别为 5.1,适用于分辨率高达 4K 的视频。
    编码选项:详细列出了编码器的参数设置,包括:
    cabac=0:不使用 CABAC 熵编码。
    ref=1:参考帧数量。
    deblock=0:0:0:去块过滤器的强度为0。
    psy=1:启用心理学优化。
    bitrate=23604:目标比特率为23604 kbps,与输入文件一致。
    qcomp=0.60:量化压缩系数。

  1. 输出文件信息
    Output #0, mp4, to ‘1744097594286.mp4’:
    Metadata:
    major_brand : mp42
    minor_version : 0
    compatible_brands: mp42isomavc1
    encoder : Lavf61.1.100
    Stream #0:0(und): Video: h264 (avc1 / 0x31637661), yuv420p(tv, bt709, progressive), 3840x2160, q=2-31, 23604 kb/s, 30 fps, 15360 tbn (default)
    Metadata:
    creation_time : 2024-02-04T21:36:53.000000Z
    handler_name : Vimeo Artax Video Handler
    vendor_id : [0][0][0][0]
    encoder : Lavc61.3.100 libx264
    Side data:
    cpb: bitrate max/min/avg: 0/0/23604000 buffer size: 0 vbv_delay: N/A
    输出文件路径:1744097594286.mp4。
    输出Metadata:
    major_brand 和 compatible_brands 与输入文件一致。
    encoder:使用的 muxer( multiplexor,复用器)版本号为 Lavf61.1.100。
    流媒体信息:
    视频流的编码格式为 H.264,分辨率为 3840x2160,比特率为 23604 kb/s。
    q=2-31:量化参数范围。
    tbn=15360:时间基数(timebase numerator)。
    Side data:关于igrams buffer的信息。

  1. 转码进度
    frame= 1462 fps= 80 q=-1.0 Lsize= 140870KiB time=00:00:48.73 bitrate=23680.1kbits/s speed=2.68x
    frame=1462:总共处理了1462帧。
    fps=80:实际转码速度为80帧每秒。
    q=-1.0:量化参数 (-1 表示自动调整)。
    Lsize=140870KiB:输出文件大小约为 140.87 MB。
    time=00:00:48.73:转码完成时长为 48.73 秒。
    bitrate=23680.1kbits/s:实际比特率为23680.1 kbps。
    speed=2.68x:转码速度是实时速度的2.68倍。

  1. 编码统计
    [libx264 @ 000001e505081300] frame I:6 Avg QP:29.67 size:814006
    [libx264 @ 000001e505081300] frame P:1456 Avg QP:32.41 size: 95713
    [libx264 @ 000001e505081300] mb I I16…4: 100.0% 0.0% 0.0%
    [libx264 @ 000001e505081300] mb P I16…4: 1.3% 0.0% 0.0% P16…4: 51.9% 0.0% 0.0% 0.0% 0.0% skip:46.8%
    [libx264 @ 000001e505081300] final ratefactor: 29.74
    [libx264 @ 000001e505081300] coded y,uvDC,uvAC intra: 41.9% 22.8% 1.1% inter: 19.3% 5.8% 0.0%
    帧类型统计:
    I帧:6个,平均QP(量化参数)为29.67,大小为814006 bytes。
    P帧:1456个,平均QP为32.41,大小为95713 bytes。
    宏块(mb)统计:
    I帧宏块:100% 使用 I16…4 模式。
    P帧宏块:
    I16…4 模式占1.3%。
    P16…4 模式占51.9%。
    skip(跳过运动补偿)占46.8%。
    final ratefactor:最终的速率因子为29.74。
    编码效率统计:
    chtěIntra(内存预测):41.9% 的Y分量、22.8% 的UV分量DC、1.1% 的UV分量AC。 -_RETRY(运动预测):19.3% 的Y分量、5.8% 的UV分量。

总结
这是一个H.264视频的转码过程,输入和输出格式均为MP4,分辨率为4K(3840x2160),比特率保持不变,使用了x264编码器进行重新编码。转码速度较快(2.68x),最终输出文件大小为约140.87 MB。

转码耗时测试

ffmpeg安装位置:E:\yla-tool\ffmpeg\ffmpeg-7.0.1-full_build\bin\ffmpeg.exe

// 获取源文件码率
String videoBitrate = getVideoBitrate(inputVideo);

简单基本命令和加了参数preset 和 b:v码率设置

文件和命令“E:\yla-tool\ffmpeg\ffmpeg-7.0.1-full_build\bin\ffmpeg.exe”, “-i”,inputVideo, “-c:v”, “libx264”, “-c:a”, “aac”, System.currentTimeMillis() + “.mp4”“E:\yla-tool\ffmpeg\ffmpeg-7.0.1-full_build\bin\ffmpeg.exe”, “-i”,inputVideo, “-c:v”, “libx264”, “-b:v”, videoBitrate+“k”, “-preset”, “ultrafast”, “-c:a”, “aac”, System.currentTimeMillis() + “.mp4”
视频雪景.mp4(
7s
23M
总比特率25116kbps
帧速率59.94帧/秒)
40s(44M 码率45243kbps)8s(19M 码率20346kbps)
视频-GreatWall.mp4(
48s
137M
总比特率23472kbps
帧速率30帧/秒)
121s(140M 码率相似)19s(140M 码率相似)

参数后续……

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2330787.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

手搓多模态-06 数据预处理

前情回顾 我们目前实现了视觉模型的编码器部分&#xff0c;然而&#xff0c;我们所做的是把一张图片编码嵌入成了许多个上下文相关的嵌入向量&#xff0c;然而我们期望的是一张图片用一个向量来表示&#xff0c;从而与文字的向量做点积形成相似度&#xff08;参考手搓多模态-01…

HCIP【路由过滤技术(详解)】

目录 1 简介 2 路由过滤方法 3 路由过滤工具 3.1 静默接口 3.2 ACL 3.3 地址前缀列表 3.4 filter-policy 3.4.1 filter-policy过滤接收路由&#xff08;以RIP为例&#xff09; 3.4.2 filter-policy过滤接收路由&#xff08;以OSPF为例&#xff09; 1 简介 路由过滤技术…

【AI插件开发】Notepad++ AI插件开发实践(代码篇):从Dock窗口集成到功能菜单实现

一、引言 上篇文章已经在Notepad的插件开发中集成了选中即问AI的功能&#xff0c;这一篇文章将在此基础上进一步集成&#xff0c;支持AI对话窗口以及常见的代码功能菜单&#xff1a; 显示AI的Dock窗口&#xff0c;可以用自然语言向 AI 提问或要求执行任务选中代码后使用&…

Vue3在ZKmall开源商城前端的应用实践与技术创新

ZKmall开源商城作为一款企业级电商解决方案&#xff0c;其前端架构基于Vue3实现了高效、灵活的开发模式&#xff0c;结合响应式设计、组件化开发与全链路性能优化&#xff0c;为多端协同和复杂业务场景提供了先进的技术支持。以下从技术架构、核心特性、性能优化等维度解析Vue3…

SpringAI+MCP协议 实战

文章目录 前言快速实战Spring AISpring AI 集成 MCP 协议Spring Mcp Client 示例Spring Mcp Server 示例 前言 尽管Python最近成为了编程语言的首选&#xff0c;但是Java在人工智能领域的地位同样不可撼动&#xff0c;得益于强大的Spring框架。随着人工智能技术的快速发展&…

[数据结构]图krusakl算法实现

目录 Kruskal算法 Kruskal算法 我们要在连通图中去找生成树 连通图&#xff1a;在无向图中&#xff0c;若从顶点v1到顶点v2有路径&#xff0c;则称顶点v1与顶点v2是连通的。如果图中任意一对顶点都是连通的&#xff0c;则称此图为连通图。 生成树&#xff1a;一个连通图的最小…

QEMU学习之路(5)— 从0到1构建Linux系统镜像

QEMU学习之路&#xff08;5&#xff09;— 从0到1构建Linux系统镜像 一、前言 参考&#xff1a;从内核到可启动镜像&#xff1a;0到1构建你的极简Linux系统 二、linux源码获取 安装编译依赖 sudo apt install -y build-essential libncurses-dev flex bison libssl-dev li…

node ---- 解决错误【Error: error:0308010C:digital envelope routines::unsupported】

1. 报错 在 Node.js 18.18.0 的版本中&#xff0c;遇到以下错误&#xff1a; this[kHandle] new _Hash(algorithm, xofLen);^ Error: error:0308010C:digital envelope routines::unsupported这个错误通常发生在运行项目或构建时&#xff0c;尤其是在使用 Webpack、Vite 或其他…

蓝桥杯——走迷宫问题(BFS)

这是一个经典的BFS算法 1. BFS算法保证最短路径 核心机制&#xff1a;广度优先搜索按层遍历所有可能的路径&#xff0c;首次到达终点的路径长度即为最短步数。这是BFS的核心优势。队列的作用&#xff1a;通过队列按先进先出的顺序处理节点&#xff0c;确保每一步探索的都是当…

详解 Redis repl_backlog_buffer(如何判断增量同步)

一、repl_backlog_buffer 复制积压缓冲区&#xff08;Replication Backlog Buffer&#xff09; 是一个环形内存区域&#xff08;Ring Buffer&#xff09;&#xff0c;用于临时保存主节点最近写入的写命令&#xff0c;以支持从节点断线重连后的增量同步。 1.1 三个复制偏移量 …

使用PyTorch实现ResNet:从残差块到完整模型训练

ResNet&#xff08;残差网络&#xff09;是深度学习中的经典模型&#xff0c;通过引入残差连接解决了深层网络训练中的梯度消失问题。本文将从残差块的定义开始&#xff0c;逐步实现一个ResNet模型&#xff0c;并在Fashion MNIST数据集上进行训练和测试。 1. 残差块&#xff08…

Scala相关知识学习总结5

1、多维数组 定义&#xff1a; val arr Array.ofDim[Double](3,4) 表示二维数组中有三个一维数组&#xff0c;每个一维数组有四个元素。 2、列表 List 不可变 List&#xff1a;默认不可变&#xff0c;可创建有序且可重复的列表&#xff0c;可使用:从右向左增加数据&#xf…

Day1:前端项目uni-app壁纸实战

uni-app官网下载HBuilder。 uni-app快速上手 | uni-app官网 点击HBuilder 安装 新建项目 工具——插件安装 安装uni-app&#xff08;vue3&#xff09; 我们先来准备一下&#xff1a; 先在wallpaper下新建目录 我已经建过了 同样&#xff0c;再在common下建images和style目录&…

光谱相机的光谱数据采集原理

光谱相机的光谱数据采集原理基于‌分光技术‌和‌光电信号转换‌&#xff0c;通过将入射光按波长分解并记录各波段的强度信息&#xff0c;最终生成包含空间和光谱维度的数据立方体。以下是详细原理分解&#xff1a; ‌1. 分光技术&#xff1a;将复合光分解为单色光‌ 光谱相机…

宏碁笔记本电脑擎7PRO搭载的 NVIDIA RTX 5080 显卡安装pytorch

宏碁笔记本电脑擎7PRO搭载的 NVIDIA RTX 5080 显卡是一款高性能移动 GPU&#xff0c;基于 NVIDIA 最新的 Blackwell 架构设计&#xff0c;通过修正架构&#xff08;Blackwell&#xff09;、显存类型与带宽&#xff08;GDDR7、960GB/s&#xff09;、Tensor Core 与 RT Core 全面…

html+css+js 实现一个贪吃蛇小游戏

目录 游戏简介 游戏功能与特点 如何玩转贪吃蛇 游戏设计与实现 HTML结构 JavaScript核心实现 代码结构&#xff1a; 效果 关于“其他游戏” 游戏简介 贪吃蛇是一款经典的单人小游戏&#xff0c;玩家通过控制蛇的移动&#xff0c;吃掉食物来增加长度&#xff0c;避免撞…

Python爬虫生成CSV文件的完整流程

引言 在当今数据驱动的时代&#xff0c;网络爬虫已成为获取互联网数据的重要工具。Python凭借其丰富的库生态系统和简洁的语法&#xff0c;成为了爬虫开发的首选语言。本文将详细介绍使用Python爬虫从网页抓取数据并生成CSV文件的完整流程&#xff0c;包括环境准备、网页请求、…

21.OpenCV获取图像轮廓信息

OpenCV获取图像轮廓信息 在计算机视觉领域&#xff0c;识别和分析图像中的对象形状是一项基本任务。OpenCV 库提供了一个强大的工具——轮廓检测&#xff08;Contour Detection&#xff09;&#xff0c;它能够帮助我们精确地定位对象的边界。这篇博文将带你入门 OpenCV 的轮廓…

医学图像分割效率大幅提升!U-Net架构升级,助力精度提升5%!

在医学图像分割领域&#xff0c;U-Net模型及其变体的创新应用正在带来显著的性能提升和效率优化。最新研究显示&#xff0c;通过引入结构化状态空间模型&#xff08;SSM&#xff09;和轻量级LSTM&#xff08;xLSTM&#xff09;等技术&#xff0c;VMAXL-UNet模型在多个医学图像数…

智能设备运行监控系统

在工业 4.0 与智能制造浪潮下&#xff0c;设备运行效率与稳定性成为企业竞争力的核心要素。然而&#xff0c;传统设备管理模式面临数据采集分散、状态分析滞后、维护成本高昂等痛点。为破解这些难题&#xff0c;设备运行监控系统应运而生&#xff0c;通过融合智能传感、5G 通信…