использование ffmpeg для разрезания видео

<p>я использую ffmpeg, чтобы вырезать раздел большого файла следующим образом:</p><pre><code>ffmpeg -i input.wmv -ss 60 -t 60 -acodec copy -vcodec copy output.wmv </code></pre><p>часть <code>-ss</code> работает нормально, но <code>-t</code> игнорируется. он корректно удаляет начальные указанные секунды, указанные с помощью <code>-ss</code>, но затем продолжает идти до конца ввода с копией.</p><p>есть ли способ использовать ffmpeg, чтобы обрезать конец видео без его перекодирования?</p>

<p>вы можете использовать опцию <code>-ss</code>, чтобы указать начальную метку времени, и опцию <code>-t</code>, чтобы указать длительность кодирования. метки времени должны быть в формате <code>hh:mm:ss.xxx</code> или в секундах (<code>s.msec</code>).</p><p>следующий код обрезает первые 30 секунд, а затем обрезает все, что происходит через 10 секунд:</p><pre><code>ffmpeg -ss 00:00:30.0 -i input.wmv -c copy -t 00:00:10.0 output.wmv ffmpeg -ss 30 -i input.wmv -c copy -t 10 output.wmv </code></pre><p>обратите внимание, что <code>-t</code> является опцией вывода и всегда должен быть указан<em> после </em><code>-i</code>.</p><p>несколько советов:</p><ul> <li>для более старых версий ffmpeg, если вы используете <code>-ss</code> после <code>-i</code>, вы получите более точный поиск за счет более медленного выполнения в целом. смотрите также: <a href="http://trac.ffmpeg.org/wiki/seeking">поиск с помощью ffmpeg</a> </li> <li> <p>вы можете использовать <code>-to</code> вместо <code>-t</code>, чтобы указать временную метку, до которой вы хотите сократить. таким образом, вместо <code>-i <input> -ss 30 -t 10</code> вы также можете сделать <code>-i <input> -ss 30 -to 40</code> для достижения того же результата.</p> </li> <li> <p>если ваш ffmpeg не поддерживает <code>-c</code> или <code>-to</code>, он, вероятно, сильно устарел. <a href="http://ffmpeg.org/trac/ffmpeg/wiki/compilationguide">скомпилируйте новую версию</a> себя или <a href="http://ffmpeg.org/download.html">загрузите статическую сборку</a> со своей домашней страницы. это действительно не сложно.</p> </li> </ul>

<p>как уже упоминалось, размещение <code>-ss</code> до (намного быстрее) или после (более точно) <code>-i</code> имеет большое значение. в разделе «быстрый и точный поиск» на странице поиска ffmpeg рассказывается, как получить оба, и я их использовал, и это имеет большое значение. обычно вы ставите <code>-ss</code> до и после <code>-i</code>, просто оставьте достаточно времени до того места, где вы хотите начать резку, чтобы получить еще один ключевой кадр. пример: если вы хотите сделать 1-минутный клип, от 9 минут 0 секунд до 10 минут 0 секунд в video.mp4, вы можете сделать это быстро и точно, используя:</p><pre><code>ffmpeg -ss 00:08:00 -i video.mp4 -ss 00:01:00 -t 00:01:00 -c copy videoclip.mp4 </code></pre><p>первый <code>-ss</code> стремится к (приблизительно) 8 мин0 с, а затем второй <code>-ss</code> точно ищет к 9 мин 0 с, а <code>-t 00:01:00</code> извлекает клип длительностью 1 мин 0 с.</p><p>также обратите внимание на этот важный момент на этой странице: «если вы используете <code>-ss</code> с <code>-c:v copy</code>, результирующий битовый поток может оказаться прерывистым, не воспроизводимым или не синхронизированным с аудиопотоком, поскольку ffmpeg вынужден использовать/разбивать только на кадры «.</p><p>это означает, что вам нужно перекодировать видео, даже если вы хотите просто скопировать его или рискнуть быть нестабильным и не синхронизированным. сначала вы можете попробовать просто <code>-c copy</code>, но если видео отстой, вам нужно будет сделать это заново.</p>

<p>я обнаружил, что <code>-ss</code> в сочетании с <code>-c copy</code> приводил к полсекундной отбивке в начале.</p><p>чтобы избежать этого, вы должны удалить <code>-c copy</code> (который по общему признанию сделает транскод).</p>

<h2>вручную</h2><p>откройте файл в медиаплеере, который будет перемещаться по кадрам, и воспроизведите файл<em> файл avisynth </em>с такими данными, как:</p><pre><code>directshowsource(("c:\downloads\video\do you want him.flv"), pixel\_type="yuy2").crop(0,0,-0,-0) subtitle("c:\downloads\video\do you want him.flv", font="arial", size=24, text\_color=$ff0000, align=3) showframenumber(scroll=true, x=336, y=27, font="arial", size=24, text_color=$ff0000) showtime(x=398, y=44, font="arial", size=24, text\_color=$ff0000) </code></pre><p>затем вырезать с точным форматом времени:</p><pre><code>ffmpeg -i "path\do you want him.flv" \ -ss 00:00:05.240 -to 00:00:08.360 \ -vcodec libx264 -acodec libvo\_aacenc \ "path\do you want him1.flv" </code></pre><p>а также</p><pre><code>ffmpeg -i "path\do you want him.flv" \ -ss 00:00:10.240 -to 00:00:14.360 \ -vcodec libx264 -acodec libvo\_aacenc \ "path\do you want him2.flv" </code></pre><p>теперь создайте текстовый файл с видеофайлами с таким содержимым, как:</p><pre><code>file 'c:\downloads\video\do you want him1.flv' file 'c:\downloads\video\do you want him2.flv' </code></pre><p>запустите ffmpeg:</p><pre><code>ffmpeg -f concat -i filelist.txt -c copy "path\newname\_joined.flv" </code></pre>

<p>для меня опция <code>-t</code> не работала, но <code>-vframes</code> работала. я предпочитаю использовать <code>#frames</code>, так как я предпочел бы сократить i-frames и выяснить gop для видео, используя <code>ffprobe</code>.</p><p>командная строка, которая работала для меня:</p><pre><code>ffmpeg -ss 60s -i input.wmv -vframes 1800 -acodec copy -vcodec copy output.wmv </code></pre><p>между прочим, размещение <code>-ss</code> перед <code>-i</code> имеет большое значение во времени выполнения.</p>

<p>как и в случае с user225366, опция -t не работает для коротких видео, но она подходит для более длинных видео. для коротких видео кажется, что -frames: v лучше. это то, что сработало для меня.</p><pre><code>ffmpeg -ss 4 -i input.mp4 -frames:v 200 -vcodec copy output.mp4 </code></pre><p>копия -acodec должна быть добавлена, если у видео есть аудио, как показывают другие ответы.</p>