123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116 |
- import configparser
- import glob
- import os
- import random
- import re
- import subprocess
- import sys
- import time
- import urllib.parse
- import json
- import requests
- from datetime import datetime, timedelta
- from urllib.parse import urlencode
- class FFmpeg():
- """
- 获取单个视频时长
- """
- @classmethod
- def get_video_duration(cls, video_url):
- ffprobe_cmd = [
- "ffprobe",
- "-i", video_url,
- "-show_entries", "format=duration",
- "-v", "quiet",
- "-of", "csv=p=0"
- ]
- output = subprocess.check_output(ffprobe_cmd).decode("utf-8").strip()
- return float(output)
- """
- 获取视频文件的时长(秒)
- """
- @classmethod
- def get_videos_duration(cls, video_file):
- result = subprocess.run(
- ["ffprobe", "-v", "error", "-show_entries", "format=duration",
- "-of", "default=noprint_wrappers=1:nokey=1", video_file],
- capture_output=True, text=True)
- return float(result.stdout)
- """
- 视频裁剪
- """
- @classmethod
- def video_tailor(cls, video_url):
- output_video_path = ''
- # 获取视频的原始宽高信息
- ffprobe_cmd = f"ffprobe -v error -select_streams v:0 -show_entries stream=width,height -of csv=p=0 {video_url}"
- ffprobe_process = subprocess.Popen(ffprobe_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
- output, _ = ffprobe_process.communicate()
- width, height = map(int, output.decode().strip().split(','))
- # 计算裁剪后的高度
- new_height = int(height * 0.7)
- # 构建 FFmpeg 命令,裁剪视频高度为原始高度的70%,并将宽度缩放为320x480
- ffmpeg_cmd = [
- "ffmpeg",
- "-i", video_url,
- "-vf", f"crop={width}:{new_height},scale=320:480",
- "-c:v", "libx264",
- "-c:a", "aac",
- "-y",
- output_video_path
- ]
- # 执行 FFmpeg 命令
- subprocess.run(ffmpeg_cmd)
- return output_video_path
- """
- 截取原视频最后一帧
- """
- @classmethod
- def video_png(cls,video_url):
- """
- png 生成图片位置
- :param video_url: 视频地址
- :return:
- """
- png = ''
- # 获取视频时长
- total_duration = cls.get_video_duration(video_url)
- time_offset = total_duration - 1 # 提取倒数第一秒的帧
- # 获取视频最后一秒,生成.jpg
- subprocess.run(
- ['ffmpeg', '-ss', str(time_offset), '-i', video_url, '-t', str(total_duration), '-vf', 'fps=1', png])
- return png
- """
- 生成片尾视频
- """
- @classmethod
- def new_pw_video(cls):
- # 添加音频到图片
- """
- png_path 图片地址
- pw_video 提供的片尾视频
- pw_duration 提供的片尾视频时长
- background_cmd 视频位置
- subtitle_cmd 字幕
- pw_path 生成视频地址
- :return:
- """
- ffmpeg_cmd = ['ffmpeg', '-loop', '1', '-i', png_path, '-i', pw_video, '-c:v', 'libx264', '-t',
- str(pw_duration), '-pix_fmt', 'yuv420p', '-c:a', 'aac', '-strict', 'experimental', '-shortest',
- '-vf', f"scale=320x480,{background_cmd},{subtitle_cmd}", pw_path]
- subprocess.run(ffmpeg_cmd)
- return pw_path
|