Python 3.x 如何使用帧单位制作时间字幕(.srt、.smi等)

Python 3.x 如何使用帧单位制作时间字幕(.srt、.smi等),python-3.x,ffmpeg,h.264,video-processing,subtitle,Python 3.x,Ffmpeg,H.264,Video Processing,Subtitle,我想创建一个制作字幕的Python脚本(滴答声时间码) 我有一个在每帧中都有时间戳的。所以我想解析这个时间戳并用它制作字幕 下面是我用ffmpeg尝试的内容 ffmpeg -y -i video.avi -vf "drawtext=fontfile=C:\Windows\Fonts\consolab.ttf: fontsize=12:fontcolor=yellow: box=1:boxcolor=black@0.4: text='TIME\: %{pts\:gmtime\:1561939200

我想创建一个制作字幕的Python脚本(滴答声时间码

我有一个在每帧中都有时间戳的。所以我想解析这个时间戳并用它制作字幕

下面是我用ffmpeg尝试的内容

ffmpeg -y -i video.avi -vf "drawtext=fontfile=C:\Windows\Fonts\consolab.ttf: fontsize=12:fontcolor=yellow: box=1:boxcolor=black@0.4: text='TIME\: %{pts\:gmtime\:1561939200}':x=(w-tw)/2:y=(h-th)/2" test.avi
输出
.avi
可以使用时间戳,但是,我需要重新编码源视频文件,这需要很多时间。 所以,我想用另一种方式,那就是制作字幕

问题是,有没有办法用帧时间制作字幕?或者有用的信息来告诉我

当前结果:

预期结果:


通过定义开始时间,您可以直接使用时间码:

ffmpeg -i source_file -c:v libx264 -vf drawtext="fontfile=C\\:/Windows/Fonts/arial.ttf:fontsize=45:timecode='10\:00\:00\:00':fontcolor='white':box=1:boxcolor='black':rate=25:x=(w-text_w)/2:y=h/1.2" -c:a aac -f mp4 output_with_TC.mp4
您还可以使用ffprobe从文件中获取时间代码,并在批处理文件中使用它

@echo off

cd C:\bin

set file=%1 

For %%A in ("%file%") do (
    Set Folder=%%~dpA
    Set Name=%%~nA

)

set "CommandLine=ffprobe -i %file% -show_entries format_tags=timecode -of default=noprint_wrappers=1"
setlocal EnableDelayedExpansion
for /F "delims=" %%I in ('!CommandLine!') do set "TC=%%I"

echo.File is: %file%
echo.TC is: %TC%

set hours=%TC:~13,2% 
set minutes=%TC:~16,2% 
set seconds=%TC:~19,2% 
set frames=%TC:~22,2% 

set h=!hours: =!
set m=!minutes: =!
set s=!seconds: =!
set f=!frames: =!

set final_TC=%h%:%m%:%s%:%f%

echo.final_TC is : %final_TC%

ffmpeg -i %file% -c:v libx264 -vf drawtext="fontfile=C\\:/Windows/Fonts/arial.ttf:fontsize=45:timecode=\'%final_TC%\':fontcolor='white':box=1:boxcolor='black@0.4':rate=25:x=1600:y=30" -c:a aac -f mp4 output_%Name%.mp4 -y

endlocal


可能会帮助您快速获得解决方案(我在这里发布了一些修改):

  • fps
    变量设置为您自己视频的fps

  • 设置
    myTimeNum
    var,方法是使用计时器增加一些
    frameNum
    计数,每FPS间隔一次

逻辑:

其中示例FPS为10

FPS= 10; frameNum = 0; myTimeNum = 0
表示每秒10次(使用计时器),您必须

myTimeNum = (1000 / FPS) * frameNum
timecode = smpte.totc(myTimeNum, fps)
frameNum++
要尝试的代码:

fps = 30
myTimeNum = 50000;
timecode = smpte.totc(myTimeNum, fps)
print timecode


#Converts frames to SMPTE timecode of arbitrary frame rate and back.
#For DF calculations use 29.976 frame rate.
#Igor Ridanovic, igor@HDhead.com


def totc(x, fps):
    """Converts frame count to SMPTE timecode.""" 
    spacer = ':'
    frHour = fps * 3600
    frSec = fps * 60
    hr = int(x // frHour)
    mn = int((x - hr * frHour) // frSec)
    sc = int((x - hr * frHour - mn * frSec) // fps)
    fr = int(round(x -  hr * frHour - mn * frSec - sc * fps))

    return(
    str(hr).zfill(2) + spacer +
    str(mn).zfill(2) + spacer +
    str(sc).zfill(2) + spacer +
    str(fr).zfill(2))

非常感谢您的回复,但是如果我使用带有drawbox的ffmpeg,ffmpeg会迫使我重新编码原始视频以输出。若我有很多大的视频文件,重新编码的过程会花费很多时间。我有一个h.264二进制文件,每个帧都有时间戳,你怎么知道?由于H264中通常不存在时间戳,因此只知道帧速率(FPS)。除非你指的是DTS和PTS等?…有时它存在于报头中。(1)给我一些H264报头字节,在那里你可以看到时间戳,我会检查发生了什么。你不是说MP4的头上有时间戳,对吧?(2) 您是否能够将单个H264帧馈送到解码器?你能跟踪“解码多少帧”的数字吗?这样你就可以用
(1000/FPS)*my_frame_num
计算时间戳了。PS:你到底想实现什么?(a) 只是一个SMPTE时间码,在视频播放时像时钟一样运行?因为FFmpeg命令就是这样做的,所以它从计算的PTS(如上面的注释)生成文本,而不读取任何H264时间戳。您想要Python中的相同文本还是(b)必须是指定帧的精确时间戳(表示从字节中提取)?此时,您正在询问如何使用Python读取字节?使用ffmpeg的DrawBox选项,我可以在视频上显示时间戳。然而,如果视频变得更大,重唱需要很多时间。所以,我不想使用DrawBox,通常我使用视频编解码器拷贝选项(-c:v拷贝),它不会对视频进行重新编码。与当前样本文件共享您:[link]()可能的结果:[link]()样本二进制文件:[link]()