linux有效裁剪视频的方式(基于ffmpeg,不改变分辨率,帧率,视频质量,不需要三方软件)

发布于:2025-05-30 ⋅ 阅读:(18) ⋅ 点赞:(0)

就是在Linux上使用OBS Studio录制一个讲座或者其他视频,可能总有些时候会多录制一段时间,但是如果使用剪映或者PR这样的工具在导出的时候总需要烦恼导出的格式和参数,比如剪映就不支持mkv格式的导出,导出成mp4格式的视频就会变得很大,有很方便的处理办法,使用ffmpeg

一. 最终效果


!!!注意!!!:还是有一点我不知道原因的问题,发现新视频虽然可以播放,但是在Linux下总是有前几秒的黑屏,在NAS端的网页播放时也加载的很慢,还是有问题的


处理前:
在这里插入图片描述
处理后:
在这里插入图片描述


二. 处理代码

2.1 读取视频或者图片信息的代码

import os
import cv2
from PIL import Image

def get_image_info(image_path):
    try:
        with Image.open(image_path) as img:
            info = {
                "类型": "图片",
                "文件名": os.path.basename(image_path),
                "格式": img.format,
                "模式": img.mode,
                "分辨率": img.size,  # (宽, 高)
                "色深": img.bits if hasattr(img, 'bits') else "未知",
                "通道数": len(img.getbands()),
                "文件大小(字节)": os.path.getsize(image_path)
            }
            return info
    except Exception as e:
        return {"错误": f"无法读取图片信息: {e}"}

def get_video_info(video_path):
    try:
        cap = cv2.VideoCapture(video_path)
        if not cap.isOpened():
            return {"错误": "无法打开视频文件"}
        info = {
            "类型": "视频",
            "文件名": os.path.basename(video_path),
            "分辨率": (int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)), int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))),
            "帧率(FPS)": cap.get(cv2.CAP_PROP_FPS),
            "总帧数": int(cap.get(cv2.CAP_PROP_FRAME_COUNT)),
            "时长(秒)": cap.get(cv2.CAP_PROP_FRAME_COUNT) / cap.get(cv2.CAP_PROP_FPS) if cap.get(cv2.CAP_PROP_FPS) > 0 else "未知",
            "编码格式": cap.get(cv2.CAP_PROP_FOURCC),
            "文件大小(字节)": os.path.getsize(video_path)
        }
        cap.release()
        return info
    except Exception as e:
        return {"错误": f"无法读取视频信息: {e}"}

def print_info(info):
    for k, v in info.items():
        print(f"{k}: {v}")

def main(file_path):
    if not os.path.isfile(file_path):
        print("文件不存在!")
        return
    ext = os.path.splitext(file_path)[1].lower()
    image_exts = ['.jpg', '.jpeg', '.png', '.bmp', '.tiff', '.gif', '.webp']
    video_exts = ['.mp4', '.avi', '.mov', '.mkv', '.flv', '.wmv', '.webm', '.mpeg', '.mpg']
    if ext in image_exts:
        info = get_image_info(file_path)
    elif ext in video_exts:
        info = get_video_info(file_path)
    else:
        # 尝试用PIL打开,失败再尝试用cv2.VideoCapture
        try:
            with Image.open(file_path) as img:
                info = get_image_info(file_path)
        except Exception:
            info = get_video_info(file_path)
    print_info(info)

if __name__ == "__main__":
    # path = input("请输入图片或视频文件路径:").strip()
    path = "/home/tipriest/output.mkv"
    main(path)
    

2.2 截取视频的代码

ffmpeg -i "深蓝学院-YY硕-访谈.mkv" -ss 00:00:00 -to 02:05:11 -c:v copy -c:a copy output.mkv

三. ffmpeg命令详细说明

要裁剪视频并保持分辨率、帧率不变,可以使用ffmpeg工具实现。具体步骤如下:

方法一:指定结束时间点裁剪(推荐)

ffmpeg -i "深蓝学院-YY硕-访谈.mkv" -ss 00:00:00 -to 01:30:00 -c:v copy -c:a copy output.mkv

参数说明:

  • -to 01:30:00:裁剪到1小时30分钟(按需替换时间)
  • -c:v copy -c:a copy:直接复制音视频编码流,避免重新编码
  • 支持精确到毫秒的格式:00:10:30.500

方法二:指定持续时间裁剪

ffmpeg -i input.mkv -t 5400 -c copy output.mkv

参数说明:

  • -t 5400:保留前5400秒(即1.5小时)
  • 总时长10631秒≈2小时57分,若需保留前2小时则 -t 7200

关键注意事项:

  1. 保持原画质参数:使用 -c copy 直接复制编码流,分辨率/帧率自动继承
  2. 时间精度优化
    • 添加 -avoid_negative_ts 1 防止时间戳错误
    • 添加 -copyts 保留原始时间戳
    ffmpeg -ss 00:09:50 -i input.mkv -ss 00:10:00 -to 00:20:00 -copyts -c copy -avoid_negative_ts 1 output.mkv
    
  3. MKV格式兼容性:MKV容器支持流复制,无需转码

验证输出信息

执行后可运行 ffprobe output.mkv 检查输出视频的时长、分辨率、帧率是否与需求一致

注:若裁剪位置不在关键帧,ffmpeg会自动跳到前一关键帧,可能导致头尾有数秒误差。如需帧级精准需重新编码(不推荐,会降低质量)


网站公告

今日签到

点亮在社区的每一天
去签到