iMovie(并非无损,但比以前更好)
iMovie v10(最初提出问题后不久发布)现在可以更好地处理更多媒体类型,因此避免了对大多数H.264(mp4,m4v,mov,AVHDC,mts,mt2s)内容进行导入重新编码。
但是,它仍将在导出时进行重新编码,因此在技术上不能无损-但是,另一个新功能是可以自定义导出质量的功能,该质量可能接近无损。我怀疑答案的这一部分可以同样适用于其他“项目驱动”的视频编辑软件(例如Premiere或Final Cut),因为我认为它们通常都对输出进行重新编码,尽管通常非常容易用于精确修整。
就个人而言,我通常认为一次重新编码不是一个大问题,但要了解您确实要求无损解决方案,所以...
无损(但方式更复杂!)
在不重新编码至少一部分视频的情况下,如何精确地剪切视频存在技术限制,并且它基本上取决于i帧频率。如果每个帧都是i帧,则可以在任何地方剪切,但是如果只有几秒钟,则只能在这些i帧处无损地剪切,而不会丢失内容或重新编码(至少一部分)。流),因此它可以从i帧开始。
ffmpeg
该SO Q&A特别提出了如何使用来在i帧之间进行剪切的问题ffmpeg
。我不知道有任何GUI应用程序可以执行此操作,但是基本上您可以运行类似以下命令:
ffmpeg -i input.m4v -vcodec copy -acodec copy -ss 00:01:20.000 -t 00:37:50.000 output.m4v
指定的两个时间是start和duration,可以将其指定为seconds或hh:mm:ss.ss
,-acodec copy
并-vcodec copy
告知ffmpeg不要重新编码。
我不确定如果剪切得太早会发生什么,但是我认为视频在遇到i帧之前基本上是空白的(或者可能是损坏的,具体取决于播放器)。因此,您可能希望在剪切之前找到最近的i框架。这个答案使用ffprobe
和解决了这个问题awk
,尽管有点尴尬。本质上,您是ffprobe
用来扫描帧并flags=K
在理想的切点之前找到最近的关键帧()。视频每一帧的完整输出如下所示:
ffprobe -select_streams v -show_frames <INPUT>
链接的答案提供此命令以在特定时间之前找到关键帧:
ffprobe -select_streams v -show_frames -v quiet INPUT.mp4 |
awk -F= '
/pict_type=/ { if (index($2, "I")) { i=1; } else { i=0; } }
/pkt_pts_time/ { if (i && ($2 >= 150)) print $2; }
' | head -n 1
最后,如果您确实需要在两个i帧之间剪切某处,则可以拆分视频并重新加入。根据此答案中的信息,它应该类似于:
ffmpeg -f concat -i list_of_videos.txt -c copy OUTPUT.mp4
list_of_videos.txt
一个简单的文本文件在哪里,列出了您要连接的文件。
摘要
iMovie对于大多数情况(自v10起)可能足够好,而且非常简单。
ffmpeg可以一点点地无损地(或非常接近地无损地)进行操作;难度的高低取决于您对精确起点的挑剔程度以及i帧的频率。