Moviepy - выходное видео не воспроизводится

Я использую библиотеку moviepy в Linux Mint 18.1.

В частности, это moviepy 0.2.3.2 на python 3.5.2

Поскольку я начинаю, я попробовал этот простой скрипт, который должен объединить два видео одно за другим:

import moviepy.editor as mp

video1 = mp.VideoFileClip("short.mp4")
video2 = mp.VideoFileClip("motivation.mp4")

final_video = mp.concatenate_videoclips([video1,video2])
final_video.write_videofile("composition.mp4")

Два видео — это короткие случайные видеоролики, которые я скачал с YouTube. Оба они отлично воспроизводятся, как с VLC, так и со стандартным видеоплеером, поставляемым с Linux Mint.

Скрипт работает нормально, без ошибок, с окончательным сообщением:

[MoviePy] >>>> Building video composition.mp4
[MoviePy] Writing audio in compositionTEMP_MPY_wvf_snd.mp3
100%|██████████████████████████████| 1449/1449 [00:23<00:00, 59.19it/s]
[MoviePy] Done.
[MoviePy] Writing video composition.mp4
100%|██████████████████████████████| 1971/1971 [11:34<00:00,  2.84it/s]
[MoviePy] Done.
[MoviePy] >>>> Video ready: composition.mp4 

Файл действительно создан, и у него тоже есть размер (около 20 МБ). Однако, когда я пытаюсь воспроизвести его, ничего не происходит: он как будто испорчен. Стандартный видеоплеер даже говорит мне, что "нет видеопотока для воспроизведения".

Если я попытаюсь сделать то же самое с интерактивной консолью и использую final_video.preview(), я получу AttributeError вместе с этой трассировкой:

In [5]: final_video.preview()
Exception in thread Thread-417:
Traceback (most recent call last):
  File "/usr/lib/python3.5/threading.py", line 914, in _bootstrap_inner
    self.run()
  File "/usr/lib/python3.5/threading.py", line 862, in run
    self._target(*self._args, **self._kwargs)
  File "<decorator-gen-211>", line 2, in preview
  File "/usr/local/lib/python3.5/dist-packages/moviepy/decorators.py", line 54, in requires_duration
    return f(clip, *a, **k)
  File "/usr/local/lib/python3.5/dist-packages/moviepy/audio/io/preview.py", line 49, in preview
    sndarray = clip.to_soundarray(tt,nbytes=nbytes, quantize=True)
  File "<decorator-gen-184>", line 2, in to_soundarray
  File "/usr/local/lib/python3.5/dist-packages/moviepy/decorators.py", line 54, in requires_duration
    return f(clip, *a, **k)
  File "/usr/local/lib/python3.5/dist-packages/moviepy/audio/AudioClip.py", line 107, in to_soundarray
    fps = self.fps
AttributeError: 'CompositeAudioClip' object has no attribute 'fps'

и видео кажется замороженным на первом кадре.

Я понятия не имею, так как все работает нормально (за исключением предварительного просмотра, который не работает из-за ошибки). Пробовал переустанавливать ffmpeg, но безуспешно: все точно так же. Без какой-либо полезной ошибки я не могу понять, как решить эту проблему. Может кто-нибудь помочь мне?

РЕДАКТИРОВАТЬ: Что такое 4 волшебные буквы? Р-Т-Ф-М! Я решил проблему, установив kwarg method из mp.concatenate_videoclips на compose, так как исходные видео имеют другой размер кадра.


person Russell Teapot    schedule 10.10.2017    source источник
comment
муви версия?   -  person sascha    schedule 11.10.2017
comment
Интересно. Я думал, что это будет эта ошибка. Но у вас уже есть более новая версия, где это было исправлено (v0.2.3.1). Возможно, этого исправления было недостаточно. Итак, если ваши видео имеют разную частоту кадров; вы можете проверить источники moviepy, чтобы узнать, что происходит. Или конвертируйте оба видео в одинаковую частоту кадров перед использованием moviepy (да, раздражает).   -  person sascha    schedule 11.10.2017
comment
довольно близко, но AttributeError здесь связано с CompositeAudioClip, а не VideoClip. В средстве отслеживания проблем @zulko заявляет, что concatenate будет приписывать fps конечному клипу только в том случае, если все клипы имеют одинаковую частоту кадров, в противном случае это двусмысленный случай и .. сделайте значение fps по умолчанию самым большим fps в списке. Это именно то поведение, которое я испытываю здесь: один клип имеет ровно 30,0 кадров в секунду, другой 29,999 ..., и если я проверю final_video.fps из интерактивной консоли, я получаю 30,0 кадров в секунду. Так что это не должно быть проблемой   -  person Russell Teapot    schedule 11.10.2017
comment
Я бы попробовал тот же код с двумя входами с равными частотами кадров. Только для отладки.   -  person sascha    schedule 11.10.2017
comment
Аааа.. очень плохо, я попытался преобразовать видео с помощью команды ffmpeg -i <input_video> -r 30 <output_video>, успешно преобразовав его в 30 кадров в секунду, но безуспешно: все по-прежнему.   -  person Russell Teapot    schedule 11.10.2017


Ответы (1)


Чтобы понять, что происходит, я решил применить более систематический подход, выполнив следующие шаги:

  1. Создайте виртуальную среду без пакетов, кроме moviepy и его зависимостей.
  2. Используйте видео из другого источника
  3. Попробуйте разные кодеки и/или другие параметры
  4. Покопайтесь в исходном коде moviepy
  5. Принести козла в жертву Ангелу Света, Обманщику, Отцу Лжи, Рычащему Льву, Сыну Погибели Сатане Люциферу

В каждом случае я буду использовать этот скрипт (test.py):

import moviepy.editor as mp

video1 = mp.VideoFileClip("short.mp4")
video2 = mp.VideoFileClip("motiv_30.mp4")

final_video = mp.concatenate_videoclips([video1,video2])
final_video.write_videofile("composition.mp4")

с небольшими изменениями, когда это необходимо. Я обновлю этот пост, когда буду следовать инструкциям.

<сильный>1. Создайте виртуальную среду

Я создал виртуальную среду с помощью virtualenv, активировал ее и установил moviepy с помощью pip. Это вывод pip freeze:

decorator==4.0.11
imageio==2.1.2
moviepy==0.2.3.2
numpy==1.13.3
olefile==0.44
Pillow==4.3.0
tqdm==4.11.2

Все с python 3.5.2.

После запуска test.py видео создается без видимых проблем. Однако видео не может быть воспроизведено ни с помощью VLC, ни с помощью видеопроигрывателя по умолчанию в Linux Mint 18.1.

Затем я заметил, что mp.concatenate_videoclips имеет kwarg method, который по умолчанию установлен на chain. В документации я прочитал, что:

- method="compose", if the clips do not have the same
  resolution, the final resolution will be such that no clip has
   to be resized.

Итак, я попытался использовать kwarg method="compose", так как два видео имеют разные размеры кадров и... это сработало. Я идиот. Ну что ж, я полагаю, никаких козлов для сатаны. Извлеченный урок: RTFM

person Russell Teapot    schedule 11.10.2017
comment
У меня была другая проблема: мое отрендеренное видео содержало части, где оно было повреждено, и другие части, где все было в порядке. Изменение метода создания решило проблему. Спасибо, что поделился! - person RealA10N; 23.09.2020
comment
@RealA10N ахах! Рад, что это помогло! - person Russell Teapot; 24.09.2020