moviepy icon indicating copy to clipboard operation
moviepy copied to clipboard

Concatenating subclips: "AttributeError: 'CompositeAudioClip' object has no attribute 'fps'"

Open helasraizam opened this issue 5 years ago • 10 comments

Expected Behavior

Concatenates and plays composite video file.

Actual Behavior

Preview freezes on first frame with the following output:

pygame 1.9.4
Hello from the pygame community. https://www.pygame.org/contribute.html
Exception in thread Thread-1:
Traceback (most recent call last):
  File "/usr/lib/python3.7/threading.py", line 917, in _bootstrap_inner
    self.run()
  File "/usr/lib/python3.7/threading.py", line 865, in run
    self._target(*self._args, **self._kwargs)
  File "<decorator-gen-100>", line 2, in preview
  File "/usr/lib/python3.7/site-packages/moviepy/decorators.py", line 54, in requires_duration
    return f(clip, *a, **k)
  File "/usr/lib/python3.7/site-packages/moviepy/audio/io/preview.py", line 49, in preview
    sndarray = clip.to_soundarray(tt, nbytes=nbytes, quantize=True)
  File "<decorator-gen-72>", line 2, in to_soundarray
  File "/usr/lib/python3.7/site-packages/moviepy/decorators.py", line 54, in requires_duration
    return f(clip, *a, **k)
  File "/usr/lib/python3.7/site-packages/moviepy/audio/AudioClip.py", line 110, in to_soundarray
    fps = self.fps
AttributeError: 'CompositeAudioClip' object has no attribute 'fps'

Steps to Reproduce the Problem

#!/usr/bin/env python3

import moviepy.editor as mpy

clip=mpy.VideoFileClip("sample.mp4")
#clip=clip.without_audio()

subclip=mpy.concatenate_videoclips([clip.subclip((1,0),(2,0)),clip.subclip((3,0),(4,0)),clip.subclip((5,0),(6,0))])

subclip.preview()

Note that uncommenting the clip=clip.without_audio() removes the error.

Specifications

  • Python Version: 3.7.0
  • Moviepy Version: 0.2.3.5
  • Platform Name: Arch Linux
  • Platform Version: 4.18.12-arch1-1-ARCH

helasraizam avatar Oct 21 '18 06:10 helasraizam

I can circumvent the error by (presumably) reinitializing the audio:

clip=mpy.VideoFileClip("sample.mp4")
clip=clip.without_audio().set_audio(clip.audio)

helasraizam avatar Oct 27 '18 09:10 helasraizam

This also reproduces if you try to extract audio from a CompositeVideoClip:

CompositeVideoClip([...]).audio.write_audiofile("my-audio.mp3") Which results in the error:

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-5-cfaefd79186f> in <module>
----> 1 CompositeVideoClip([...]).audio.write_audiofile("my-audio.mp3")


<C:\Users\zainr\Anaconda3\envs\clip-it\lib\site-packages\decorator.py:decorator-gen-198> in write_audiofile(self, filename, fps, nbytes, buffersize, codec, bitrate, ffmpeg_params, write_logfile, verbose, logger)

~\Anaconda3\envs\clip-it\lib\site-packages\moviepy\decorators.py in requires_duration(f, clip, *a, **k)
     52         raise ValueError("Attribute 'duration' not set")
     53     else:
---> 54         return f(clip, *a, **k)
     55 
     56 

~\Anaconda3\envs\clip-it\lib\site-packages\moviepy\audio\AudioClip.py in write_audiofile(self, filename, fps, nbytes, buffersize, codec, bitrate, ffmpeg_params, write_logfile, verbose, logger)
    189         """
    190         if not fps:
--> 191             if not self.fps:
    192                 fps = 44100
    193             else:

AttributeError: 'CompositeAudioClip' object has no attribute 'fps'

ZainRizvi avatar Mar 03 '19 03:03 ZainRizvi

I think composite clips dont get an fps automatically if the different clips have different FPSs. You can always set a fps, for instance with newclip=clip.set_fps(25)

On Sun, 3 Mar 2019, 03:20 Zain Rizvi, [email protected] wrote:

This also reproduces if you try to extract audio from a CompositeVideoClip:

CompositeVideoClip([...]).audio.write_audiofile("my-audio.mp3") Which results in the error:


AttributeError Traceback (most recent call last) in ----> 1 CompositeVideoClip([...]).audio.write_audiofile("my-audio.mp3")

<C:\Users\zainr\Anaconda3\envs\clip-it\lib\site-packages\decorator.py:decorator-gen-198> in write_audiofile(self, filename, fps, nbytes, buffersize, codec, bitrate, ffmpeg_params, write_logfile, verbose, logger)

~\Anaconda3\envs\clip-it\lib\site-packages\moviepy\decorators.py in requires_duration(f, clip, *a, **k) 52 raise ValueError("Attribute 'duration' not set") 53 else: ---> 54 return f(clip, *a, **k) 55 56

~\Anaconda3\envs\clip-it\lib\site-packages\moviepy\audio\AudioClip.py in write_audiofile(self, filename, fps, nbytes, buffersize, codec, bitrate, ffmpeg_params, write_logfile, verbose, logger) 189 """ 190 if not fps: --> 191 if not self.fps: 192 fps = 44100 193 else:

AttributeError: 'CompositeAudioClip' object has no attribute 'fps'

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/Zulko/moviepy/issues/863#issuecomment-468983731, or mute the thread https://github.com/notifications/unsubscribe-auth/ABkeKgJVR84RnNPZ1842XaKx7DdN0zTNks5vSz-NgaJpZM4XyS0A .

Zulko avatar Mar 03 '19 13:03 Zulko

I have the same problem with moviepy 1.0.0, pygame 1.9.5, python 2.7.15 on ubuntu 18.04. However, the solution provided by @helasraizam doesn't work for me.

I also tried with python3, moviepy 1.0.0, pygame 1.9.6 and got the same error.

Rendering to a file works correctly.

mattvenn avatar Apr 27 '19 10:04 mattvenn

dirty hack while trying to trace the issue (at least I can use preview now): in AudioClip.py, change:

if fps is None:
    fps = self.fps

to

if fps is None:
    fps = 44100

mattvenn avatar Apr 27 '19 10:04 mattvenn

dirty hack while trying to trace the issue (at least I can use preview now): in AudioClip.py, change:

if fps is None:
    fps = self.fps

to

if fps is None:
    fps = 44100

Yes, that's actually a bug, because CompositeVideo/Audio doesn't have fps attribute. So you have to pass it to the function so it won't get to the bugged line if not self.fps:

if not fps:
    if not self.fps:
        fps = 44100
    else:
        fps = self.fps

clip = AudioFileClip(source_file) clip2 = [...] audio = CompositeAudioClip([clip, clip2, clipN...]) audio.write_audiofile('{}.mp3'.format(self.clip.get('uuid')), fps=clip.fps)

Kurara avatar Aug 14 '19 11:08 Kurara

final_clip = CompositeAudioClip(arr)
final_clip.fps = 44100
final_clip.write_audiofile('res.mp3')

maybe this is a workaround :)

misland avatar Apr 22 '20 05:04 misland

I had the same problem as helasraizam when using 'concatenate_videoclips' and 'preview'. His workaround didn't work for me, but the following did:

#!/usr/bin/env python3

import moviepy.editor as mpy

clip=mpy.VideoFileClip("sample.mp4")

subclip=mpy.concatenate_videoclips([clip.subclip((1,0),(2,0)),clip.subclip((3,0),(4,0)),clip.subclip((5,0),(6,0))])
 
aud = subclip.audio.set_fps(44100)
subclip = subclip.without_audio().set_audio(aud)
subclip.preview()

astridcasadei avatar Oct 26 '20 23:10 astridcasadei

moviepy 1.0.3 final_audio = CompositeAudioClip([original_audio, bg_music]) final_audio.write_audiofile(os.path.join(MIX_AUDIO_DIR, "mix.mp3")) get error AttributeError: 'CompositeAudioClip' object has no attribute 'fps' change AudioClip.py line 191 to: if not fps: fps = 44100 # if not self.fps: # fps = 44100 # else: ` # fps = self.fps`` work ok

seesee777 avatar Jun 07 '22 15:06 seesee777

astridcasadei Thank you very much, everything worked out for me

proctorhuc avatar Jul 20 '22 19:07 proctorhuc