Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix AttributeError: 'NoneType' object has no attribute 'stdout' for all versions of Python #1185

Merged
merged 4 commits into from
May 7, 2020

Conversation

tburrows13
Copy link
Collaborator

This supersedes #1059, and includes the test from it, but solves the problem in a slightly different way, as suggested in #938. However, without the self.proc.wait() line, the change made it incompatible with Python <3.7 on Windows, which is why the fix has taken so long. With this PR, the dealings with subprocess.Popen should be consistent between VideoFileClips and AudioFileClips.

I could see an argument for implementing #1059 for both Video and Audio, but because this fix is intended for the v1.0 branch, I didn't want to change the recommended way of closing/deleting clips.

I intend to release this very soon as a v1.0.3, and then merge it into the v2 branch.

@coveralls
Copy link

coveralls commented May 7, 2020

Coverage Status

Coverage increased (+0.3%) to 65.16% when pulling 72e9c69 on tburrows13:fix-v1.0-4 into d54c195 on Zulko:v1.0.x.

@tburrows13
Copy link
Collaborator Author

tburrows13 commented Jun 10, 2020

Hello @SimoneMender. I'm sorry to hear that you are still experiencing problems. Would you be able to post the complete error callback, a small complete piece of code that demonstrates the error, and (if possible) a mp4 file that fails when used as input?

These 3 things should make it very easy for someone to find out where the error is and fix it.

Repository owner deleted a comment from SimoneMender Jun 10, 2020
@tburrows13
Copy link
Collaborator Author

@SimoneMender sorry, your comment appear twice on my screen, so I deleted the second one. Now the first one has disappeared as well, so that might have been my fault.

Here's your original message:

Hi all,

I still get the error message:

s = self.proc.stdout.read(self.nchannels*chunksize*self.nbytes)
AttributeError: 'NoneType' object has no attribute 'stdout'"

It is very strange that this is dependent on the video file. I leave the code exactly the same, but if I use a different mp4 file as input, an mp4 output is created without any problems. I would be happy if someone has another idea where the mistake could come from. Thanks!

Ubuntu 16.04.6
Python 3.7.7

Problem occurs with:

moviepy 2.0.0.dev1
moviepy-1.0.3
moviepy-1.0.2
moviepy-1.0.1
moviepy-1.0.0

@SimoneMender
Copy link

SimoneMender commented Jun 10, 2020

@tburrows13 Thanks for your quick answer!

Here is the complete error message:

Moviepy - Building video test.mp4.
MoviePy - Writing audio in testTEMP_MPY_wvf_snd.mp3
chunk:   0%|                                                                                        | 0/67 [00:00<?, ?it/s, now=None]Traceback (most recent call last):
  File "make_movie_issue.py", line 64, in <module>
    stop = 23 # and change this to 4, there will be no problems
  File "make_movie_issue.py", line 56, in main
    final_clip.write_videofile('test.mp4', 20)
  File "<decorator-gen-55>", line 2, in write_videofile
  File "/home/simone/.local/SMDanaconda/envs/movie/lib/python3.7/site-packages/moviepy/decorators.py", line 54, in requires_duration
    return f(clip, *a, **k)
  File "<decorator-gen-54>", line 2, in write_videofile
  File "/home/simone/.local/SMDanaconda/envs/movie/lib/python3.7/site-packages/moviepy/decorators.py", line 135, in use_clip_fps_by_default
    return f(clip, *new_a, **new_kw)
  File "<decorator-gen-53>", line 2, in write_videofile
  File "/home/simone/.local/SMDanaconda/envs/movie/lib/python3.7/site-packages/moviepy/decorators.py", line 22, in convert_masks_to_RGB
    return f(clip, *a, **k)
  File "/home/simone/.local/SMDanaconda/envs/movie/lib/python3.7/site-packages/moviepy/video/VideoClip.py", line 298, in write_videofile
    logger=logger)
  File "<decorator-gen-45>", line 2, in write_audiofile
  File "/home/simone/.local/SMDanaconda/envs/movie/lib/python3.7/site-packages/moviepy/decorators.py", line 54, in requires_duration
    return f(clip, *a, **k)
  File "/home/simone/.local/SMDanaconda/envs/movie/lib/python3.7/site-packages/moviepy/audio/AudioClip.py", line 210, in write_audiofile
    logger=logger)
  File "<decorator-gen-9>", line 2, in ffmpeg_audiowrite
  File "/home/simone/.local/SMDanaconda/envs/movie/lib/python3.7/site-packages/moviepy/decorators.py", line 54, in requires_duration
    return f(clip, *a, **k)
  File "/home/simone/.local/SMDanaconda/envs/movie/lib/python3.7/site-packages/moviepy/audio/io/ffmpeg_audiowriter.py", line 169, in ffmpeg_audiowrite
    logger=logger):
  File "/home/simone/.local/SMDanaconda/envs/movie/lib/python3.7/site-packages/moviepy/audio/AudioClip.py", line 86, in iter_chunks
    fps=fps, buffersize=chunksize)
  File "<decorator-gen-44>", line 2, in to_soundarray
  File "/home/simone/.local/SMDanaconda/envs/movie/lib/python3.7/site-packages/moviepy/decorators.py", line 54, in requires_duration
    return f(clip, *a, **k)
  File "/home/simone/.local/SMDanaconda/envs/movie/lib/python3.7/site-packages/moviepy/audio/AudioClip.py", line 127, in to_soundarray
    snd_array = self.get_frame(tt)
  File "<decorator-gen-11>", line 2, in get_frame
  File "/home/simone/.local/SMDanaconda/envs/movie/lib/python3.7/site-packages/moviepy/decorators.py", line 89, in wrapper
    return f(*new_a, **new_kw)
  File "/home/simone/.local/SMDanaconda/envs/movie/lib/python3.7/site-packages/moviepy/Clip.py", line 93, in get_frame
    return self.make_frame(t)
  File "/home/simone/.local/SMDanaconda/envs/movie/lib/python3.7/site-packages/moviepy/audio/AudioClip.py", line 297, in make_frame
    for c, part in zip(self.clips, played_parts)
  File "/home/simone/.local/SMDanaconda/envs/movie/lib/python3.7/site-packages/moviepy/audio/AudioClip.py", line 298, in <listcomp>
    if (part is not False)]
  File "<decorator-gen-11>", line 2, in get_frame
  File "/home/simone/.local/SMDanaconda/envs/movie/lib/python3.7/site-packages/moviepy/decorators.py", line 89, in wrapper
    return f(*new_a, **new_kw)
  File "/home/simone/.local/SMDanaconda/envs/movie/lib/python3.7/site-packages/moviepy/Clip.py", line 93, in get_frame
    return self.make_frame(t)
  File "/home/simone/.local/SMDanaconda/envs/movie/lib/python3.7/site-packages/moviepy/Clip.py", line 136, in <lambda>
    newclip = self.set_make_frame(lambda t: fun(self.get_frame, t))
  File "/home/simone/.local/SMDanaconda/envs/movie/lib/python3.7/site-packages/moviepy/Clip.py", line 187, in <lambda>
    return self.fl(lambda gf, t: gf(t_func(t)), apply_to,
  File "<decorator-gen-11>", line 2, in get_frame
  File "/home/simone/.local/SMDanaconda/envs/movie/lib/python3.7/site-packages/moviepy/decorators.py", line 89, in wrapper
    return f(*new_a, **new_kw)
  File "/home/simone/.local/SMDanaconda/envs/movie/lib/python3.7/site-packages/moviepy/Clip.py", line 93, in get_frame
    return self.make_frame(t)
  File "/home/simone/.local/SMDanaconda/envs/movie/lib/python3.7/site-packages/moviepy/audio/io/AudioFileClip.py", line 77, in <lambda>
    self.make_frame = lambda t: self.reader.get_frame(t)
  File "/home/simone/.local/SMDanaconda/envs/movie/lib/python3.7/site-packages/moviepy/audio/io/readers.py", line 182, in get_frame
    self.buffer_around(fr_min)
  File "/home/simone/.local/SMDanaconda/envs/movie/lib/python3.7/site-packages/moviepy/audio/io/readers.py", line 243, in buffer_around
    self.seek(new_bufferstart)
  File "/home/simone/.local/SMDanaconda/envs/movie/lib/python3.7/site-packages/moviepy/audio/io/readers.py", line 141, in seek
    self.skip_chunk(pos-self.pos)
  File "/home/simone/.local/SMDanaconda/envs/movie/lib/python3.7/site-packages/moviepy/audio/io/readers.py", line 103, in skip_chunk
    s = self.proc.stdout.read(self.nchannels*chunksize*self.nbytes)
AttributeError: 'NoneType' object has no attribute 'stdout'

While creating an example, I found another curiosity. When I call my function with:

if __name__ == '__main__':
    main(
        w=1280,
        h=720,
        clip="medicaltraining.mp4",
        start = 20,
        stop = 23
    )

I'll create the error above. When I change the start and stop time of my function to

if __name__ == '__main__':
    main(
        w=1280,
        h=720,
        clip="medicaltraining.mp4",
        start = 2,
        stop = 4
    )

mp4 file is produced without any problems. As the input file "medicaltraining.mp4", is longer than 23 s I can't understand this.
Find code and "medicaltraining.mp4" here: https://drive.google.com/file/d/1QH9vjrYBFvJmlnj222KCvYnSanzMu29n/view?usp=sharing

@tburrows13
Copy link
Collaborator Author

tburrows13 commented Jun 10, 2020

Ok, I've investigated and found a fix. Your problem is that you are closing the VideoFileClip prematurely by using it with the with ... as. When that exits, it closes the clip. Once the clip is closed, you cannot then do anything with it, such as use it as a base for writing to video.

The solution is to indent the following 2 lines:

    final_clip = mp.CompositeVideoClip(
        [
            clip_margin,
            txt_signatur.set_duration(clip_margin.duration),
            txt_title.set_duration(clip_margin.duration),
        ]
    )

    final_clip.write_videofile('test.mp4', 20)

so that they are inside the with section or stop using with entirely and just assign c as a normal variable.

The reason that it works when start=2, stop=4 is that when the clip is created, it stores some data near time=0 in its buffer, which apparently includes at least 4 seconds of data, so it never actually reads from the disk after closing.

@SimoneMender
Copy link

That solved my problem! Thank you very much!

@tburrows13 tburrows13 added the bug-fix For PRs and issues solving bugs. label Jun 16, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug-fix For PRs and issues solving bugs.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants