短视频利器 ffmpeg (2)

ffmpeg 官网这样写到

Converting video and audio has never been so easy.

如何轻松简单的使用:

1、下载

官网:http://www.ffmpeg.org

安装参考文档:

https://blog.csdn.net/qq_36765018/article/details/139067654

2、安装

bash 复制代码
# 启用RPM Fusion仓库。你可以选择免费或非免费仓库。对于ffmpeg,你通常需要免费仓库。
sudo yum localinstall --nogpgcheck https://download1.rpmfusion.org/free/el/rpmfusion-free-release-7.noarch.rpm

# 启用仓库后,你可以安装ffmpeg:
sudo yum install ffmpeg

#通过检查ffmpeg版本来验证安装:
ffmpeg -version

ffmpeg version 3.4.13 Copyright (c) 2000-2023 the FFmpeg developers
built with gcc 4.8.5 (GCC) 20150623 (Red Hat 4.8.5-44)

libavutil      55. 78.100 / 55. 78.100
libavcodec     57.107.100 / 57.107.100
libavformat    57. 83.100 / 57. 83.100
libavdevice    57. 10.100 / 57. 10.100
libavfilter     6.107.100 /  6.107.100
libavresample   3.  7.  0 /  3.  7.  0
libswscale      4.  8.100 /  4.  8.100
libswresample   2.  9.100 /  2.  9.100
libpostproc    54.  7.100 / 54.  7.100

#如果在使用RPM Fusion仓库时遇到任何问题,你可以尝试使用--enablerepo选项来显式指定仓库:
#sudo yum --enablerepo=rpmfusion-free install ffmpeg

3、使用场景

3.1 视频格式转换

bash 复制代码
手机主流视频格式:
"mp4", "avi", "rmvb",
苹果手机默认是 mov : (需要把这种格式进行格式转换)

# 格式转换,先转为mp4 然后再进行处理

仅将其流式传输到Adobe Premiere Pro 等一些应用程序所需的新容器(mp4)而不编码 (fast)的命令为
ffmpeg -i input.mov -qscale 0 output.mp4

注释中提到的替代,它以最佳质量(-qscale 0)重新编码
ffmpeg -i fengj.mov -q:v 0 fengj.mp4

3.2、视频切图片(缺点是文件有点大,比原视频还大)

bash 复制代码
从视频文件或gif图片中逐帧提取图片,并加上编号。(很有意思,这里演示视频格式,gif图片你可以试下。)
ffmpeg -i video.mp4 frame_%d.png

4、提取视频文件指定时间点的1帧,下面演示的是提取第2秒的1帧。
ffmpeg -ss 00:02 -i fengj.mp4 -frames 1  -f image2 fengj0002.png

3.3、给视频加文字水印,颜色为红色,水印内容为LinuxTime。水印位置对应命令中的x轴和y轴。(待验证)

bash 复制代码
ffmpeg -hwaccel cuvid -i fengj1.mp4 -c:v libx264 -c:a copy  -vf "drawtext=fontfile=zh.ttf:text='LinuxTime':x=1200:y=900:fontsize=50:fontcolor=red:shadowy=2" fengj2.mp4

3.4、视频切片

bash 复制代码
ffmpeg -y -i shouye_202462117216.mp4 -vcodec copy -acodec copy -vbsf h264_mp4toannexb video_xiongmao/shouye.ts

ffmpeg -i video_xiongmao/shouye.ts -c copy -map 0 -f segment -segment_list video_xiongmao/shouye.m3u8 -segment_time 1 video_xiongmao/shouye-%04d.ts

4、shell 脚本编写

因为需要使用 java 或者其他语言调用 这个软件,执行相关命令,所有编写如下脚本。方便调用

4.1、视频文件转ts容器,根据不同的视频编码,确定使用不同的 比特流过滤器

bash 复制代码
#!/bin/bash

# chmod +x convert_mp4_to_ts.sh
# 检查是否提供了两个参数
if [ "$#" -ne 2 ]; then
    echo "Usage: $0 input.mp4 output.ts"
    exit 1
fi

# 获取输入和输出文件名
input_file="$1"
output_file="$2"

# 期待的视频编码
expected_codec="h264"

# 使用ffprobe获取视频编码
actual_codec=$(ffprobe -v error -select_streams v:0 -show_entries stream=codec_name -of default=noprint_wrappers=1:nokey=1 "$input_file")

# 检查编码类型
if [ "$actual_codec" = "$expected_codec" ]; then
    echo "The video is encoded with H.264."
    # 使用ffmpeg转换视频:将MP4文件转换为TS格式
    ffmpeg -y -i "$input_file" -vcodec copy -acodec copy -vbsf h264_mp4toannexb "$output_file"
else
    echo "The video is NOT encoded with H.264. It is encoded with $actual_codec."
    ffmpeg -y -i "$input_file" -c:v libx264 -preset veryfast -crf 23 -c:a aac -b:a 128k -movflags +faststart "$output_file"
fi

# 检查ffmpeg执行结果
if [ $? -eq 0 ]; then
    echo "Video conversion successful."
else
    echo "Video conversion failed. Check the logs for more information."
fi

4.2、将ts 容器进行切片

bash 复制代码
#!/bin/bash

# 文件可执行 chmod +x convert_video.sh
# 检查是否提供了三个参数
if [ "$#" -ne 3 ]; then
    echo "Usage: $0 input.ts output.m3u8 output.ts"
    exit 1
fi

# 获取输入和输出文件名
input_file="$1"
m3u8_file="$2"
output_file="$3"

# 使用ffmpeg转换视频: 将 ts 文件进行切片,并输出为 m3u8 文件和 切片文件
ffmpeg -y -i "$input_file" -c copy -map 0 -f segment -segment_list "$m3u8_file" -segment_time 1 "$output_file"

# 检查ffmpeg执行结果
if [ $? -eq 0 ]; then
    echo "Video conversion successful."
else
    echo "Video conversion failed. Check the logs for more information."
fi

5、java 中如何调用

java 复制代码
  public static void main(String[] args) {

        executeCommandForScript(Arrays.asList("sh", "/xxxx.sh", "sourceFile", "outputFile"));

    }


public static void executeCommandForScript(List<String> command) {
        // 使用ProcessBuilder执行命令
        try {
            log.info("---------->>>>command:{}", StringUtils.join(command, " "));
            ProcessBuilder pb = new ProcessBuilder(command);
            Process process = pb.start();
            // 获取并打印命令的输出
            //Thread stdoutThread = readStream(process.getInputStream(), "OUTPUT");
            //Thread stderrThread = readStream(process.getErrorStream(), "ERROR");
            //stdoutThread.start();
            //stderrThread.start();
            // 等待命令执行完成
            int exitCode = process.waitFor();
            if (exitCode == 0) {
                log.info("Video conversion completed successfully.");
            } else {
                log.error("Video conversion failed with exit code: " + exitCode);
            }
            // 确保读取线程完成
            //stdoutThread.join();
            //stderrThread.join();
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
    }

6、HTML验证

比如使用了 4.1和4.2 的脚本进行切片处理后,如何使用

可以来一个简单的 nginx配置,

bash 复制代码
    # 视频调试
    location  / {
        root  /home/minio/data/xxx/video_test;
   
        try_files $uri $uri/ /index.html;
        index  index.html index.htm;
        proxy_set_header   X-Real-IP         $remote_addr;
        proxy_set_header   Host              $http_host;
        proxy_set_header   X-Forwarded-For   $proxy_add_x_forwarded_for;
        error_page 405 =200 @405;
      }

编写一个简单的index.html 文件

html 复制代码
<!DOCTYPE html>
<html>
<head> 
<meta charset="utf-8"> 
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="Access-Control-Allow-Origin" content="*">
    <title>H5播放m3u8文件</title>
    <!-- <script src="https://cdn.jsdelivr.net/hls.js/latest/hls.min.js"></script> -->
    <script src="hls.min.js"></script>

<style>
  .centered-video-container {
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh; /* Full height of the viewport */
  }
  video {
    max-width: 100%; /* To prevent the video from overflowing the container */
  }
</style>
</head>
<body>
<div class="centered-video-container">
  <video id="video"  controls>
  Your browser does not support the video tag.
  </video>
</div>
</body>
<script>
  var m3u8FilePath = "20240627151016AA001.m3u8";

  if (Hls.isSupported()) {
    var video = document.getElementById('video');
   // video.play();
    var hls = new Hls();
    hls.loadSource(m3u8FilePath);

    hls.attachMedia(video);
    hls.on(Hls.Events.MANIFEST_PARSED, function() {
      video.play();
    });
  } else if (video.canPlayType('application/vnd.apple.mpegURL')) {
    video.src = m3u8FilePath;
    video.addEventListener('loadedmetadata', function() {
      video.play();
    });
  }
</script>
</html>

小结:

使用 ffmpeg 做为短视频 工具,非常方便,有很多点值得探索,本文主要分享了, ffmpeg如果下载 ,安装,使用。并编写通用可执行shell 脚本,方便程序语言 在对用户上传的视频文件进行切片调用。

其中 m3u8 文件,记录了一个播放文件的顺序列表。方便在网络低带宽的情况下,依然可以满足用户观看视频的需求。

其他文章

ffmpeg命令中文手册-腾讯云开发者社区-腾讯云

ffmpeg命令中文手册-腾讯云开发者社区-腾讯云

相关推荐
开开心心就好2 小时前
Word双击预览图片插件弥补Word功能缺失
人工智能·python·智能手机·ocr·电脑·word·音视频
Yeauty5 小时前
你那条 ffmpeg 命令,一键翻成 Rust builder 代码
开发语言·rust·ffmpeg
tedcloud12315 小时前
OmniRoute怎么部署?开源AI模型路由平台Linux部署教程
linux·服务器·人工智能·开源·音视频
潜创微科技19 小时前
8K HDMI 2.1 多源切换芯片方案,一颗芯片搞定长线不黑屏
音视频
音视频牛哥19 小时前
一款优秀的视频直播软件应具备哪些核心功能?结合 SmartMediaKit 谈实时音视频系统的能力边界
音视频·视频直播·低延迟rtsp播放器·gb28181接入·rtsp服务器·低延迟rtmp播放器·鸿蒙next rtsp
AI小码19 小时前
把动作「画」给视频世界模型,跨本体双向推演,李飞飞参与
大数据·人工智能·算法·ai·大模型·音视频·编程
嵌入式-老费21 小时前
esp32开发与应用(边采样边播放音频)
音视频
中微极客1 天前
Veo视频生成与Gemini Agent平台集成实践
数据库·人工智能·oracle·音视频
码龙-DragonCoding1 天前
一键批量提取音频、提取视频
android·音视频·提取
阿童木写作1 天前
Temu商品图批量翻译工具免费,AI视频字幕翻译+智能抠图
人工智能·python·音视频