MoviePy: Concatenating video clips causes weird glitches in final video - python

Is there a way to successfully always patch up any clips together in such a way that prevents weird glitches? I put together a .mp4 from smaller .mp4 files and I got a final video with weird glitches. I am running Python 3.6.1 on Windows 10 through Sublime Text 3. I used MoviePy to do the concatenation.
The code:
from moviepy.editor import VideoFileClip, concatenate_videoclips
import os.path
path = "C:/Users/blah/videos/out/"
cliparray = []
for filename in os.listdir(path):
cliparray.append(VideoFileClip(path + filename))
final_clip = concatenate_videoclips(cliparray)
final_clip.write_videofile(path + "concatenatedvideo.mp4", codec = "libx264")
The weird glitches:
One of the clips turns into a 3x3 grid of smaller clips.
Another has the audio not lined up with the video
Another is sped up faster than what was normal.

I had also glitch while concatenating different video clips. Some had different resolutions and that was making output video file with some sort of glitches. I fixed it with
final_clip = concatenate_videoclips(cliparray, method='compose')
Resulting output was without any glitch, but since they have different resolutions, the moviepy assigns highest resolution among video clips. To fix this you might just crop to same size.

from moviepy.editor import *
#load video 1 in to variable
video_1 = VideoFileClip('video1.mp4')
#load video 2 in to variable
video_2 = VideoFileClip('video2.mp4')
clips = [video_1, video_2]
# concatenating both the clips
final = concatenate_videoclips(clips,method='compose')
#writing the video into a file / saving the combined video
final.write_videofile("merged.mp4")

Related

How can i set an audio file for video clip with moviepy without re encoding

So far i tried:
from moviepy.editor import *
videoclip = VideoFileClip("filename.mp4")
audioclip = AudioFileClip("audioname.mp3")
new_audioclip = CompositeAudioClip([audioclip])
videoclip.audio = new_audioclip
videoclip.write_videofile("new_filename.mp4")
But it takes very long time.
I'd like to do it without re encoding. i also prefer opening video or audio clip from bytes in moviepy
One way to do it is using ffmpeg_merge_video_audio from FFMPEG tools.
ffmpeg_merge_video_audio - merges video file video and audio file audio into one movie file output.
By default the merging is performed without re-encoding.
Code sample:
from moviepy.video.io import ffmpeg_tools
ffmpeg_tools.ffmpeg_merge_video_audio("filename.mp4", "audioname.mp3", 'new_filename.mp4') # Merge audio and video without re-encoding
Note:
As far as I know, it's not possible to do it "from bytes" using MoviePy.

Add audio to video using moviepy

Title basically explains it. Trying to add audio to a video. I have a sequence of mp3 files that I want to play sequentially during the video. There're no errors or anything with the code but when I run the code theres still no audio in the video. Just a recreation of the old video with no audio (the original video doesnt have audio either).
video = VideoFileClip("finished_video.mp4")
title_clip = AudioFileClip("title.mp3")
audio_list = [title_clip]
for x in range(1, counter):
audio = AudioFileClip("p{}.mp3".format(x))
audio_list.append(audio)
video.set_audio(audio_list)
video.write_videofile("new_filename.mp4")
it works for me
from moviepy.editor import *
videoclip = VideoFileClip("sample.mp4")
audioclip = AudioFileClip("sample_audio.mp3")
new_audioclip = CompositeAudioClip([audioclip])
videoclip.audio = new_audioclip
videoclip.write_videofile("output.mp4")
use CompositeAudioClip to merge both files.
I had the same issue. It seems like set_audio() doesn't actually set it, but returns the new video combined with the audio.
This is the way I did it :
final_video = video.set_audio(audio_list)
final_video.write_videofile("new_filename.mp4")
Hope that helps !

video concatenation using python breaks video in chunks

Hi so we are using python to concatenate two videos together but we are facing issue to make the video visible on android and iOS device. By using this the second video which needs to be attached in the end, breaks down into small chunks and becomes distorted. I have attached the output of the video also. Watch the last five seconds of that video.
Output :
https://drive.google.com/file/d/1uwhUG03Q_92QmHiFd_VrecBwbWGTfwvP/view
we are using this :
# Import everything needed to edit video clips
from moviepy.editor import *
# loading video dsa gfg intro video
clip = VideoFileClip("v4.mp4")
# getting subclip as video is large
clip1 = clip.subclip(0, 5)
# loading video gfg
clipx = VideoFileClip("v3.mp4")
# getting subclip
clip2 = clipx.subclip(0, 3)
clip2.ipython_display(width = 480)
# clip list
clips = [clip1, clip2]
# concatenating both the clips
final = concatenate_videoclips(clips)
#final_clip.write_videofile("new.mp4")
# showing final clip
final.ipython_display(width = 480)

moviepy ruining video after combining them

I'm trying to make a program that downloads videos from TikTok and combines all the separate videos into one .mp4 file and moves the final video to a folder on my desktop. I've been able to make it download all the videos and when I watch the separate videos they play fine however when I combine the videos some of the videos are messed up and look like this but the audio is fine.
#slecting all .mp4 files
video_files = glob.iglob("*.mp4")
print(video_files)
clips = []
for clip in video_files: # For each mp4 file name
clips.append(VideoFileClip(clip)) # Store them as a VideoFileClip and add to the clips list
today = date.today()
final = concatenate_videoclips(clips) # Concatenate the VideoFileClips
final.write_videofile(f"{today}.mp4", codec="libx264")
#moving completed video to folder on desktop
shutil.move(f'{today}.mp4', '/Users/jacobmarrandio/Desktop/done_videos/')
thanks for any help
You want to ensure that all of your videos are of the same size before concatenating. Or, you could modify the smaller clips to have a black margin by filling up space by making this change:
final = concatenate_videoclips(clips, method='compose')

Moviepy unable to read duration of file

I have been using Moviepy to combine several shorter video files into hour long files. Some small files are "broken", they contain video but was not completed correctly (i.e. they play with VLC but there is no duration and you cannot skip around in the video).
I noticed this issue when I try to create a clip using VideoFileClip(file) function. The error that comes up is:
MoviePy error: failed to read the duration of file
Is there a way to still read the "good" frames from this video file and then add them to the longer video?
UPDATE
To clarify, my issue specifically is with the following function call:
clip = mp.VideoFileClip("/home/test/"+file)
Stepping through the code it seems to be an issue when checking the duration of the file in ffmpeg_reader.py where it looks for the duration parameter in the video file. However, since the file never finished recording properly this information is missing. I'm not very familiar with the way video files are structured so I am unsure of how to proceed from here.
You're correct. This issue arises commonly when the video duration info is missing from the file.
Here's a thread on the issue: GitHub moviepy issue 116
One user proposed the solution of using MP4Box to convert the video using this guide: RASPIVID tutorial
The final solution that worked for me involved specifying the path to ImageMagick's binary file as WDBell mentioned in this post.
I had the path correctly set in my environment variables, but it wasn't till I specificaly defined it in config_defaults.py that it started working:
I solved it in a simpler way, with the help of VLC I converted the file to the forma MPEG4 xxx TV/device,
and you can now use your new file with python without any problem
xxx = 720p or
xxx = 1080p
everything depends on your choice on the output format
I already answered this question on the blog: https://github.com/Zulko/moviepy/issues/116
This issue appears when VideoFileClip(file) function from moviepy it looks for the duration parameter in the video file and it's missing. To avoid this (in those corrupted files cases) you should make sure that the total frames parameter is not null before to shoot the function: clip = mp.VideoFileClip("/home/test/"+file)
So, I handled it in a simpler way using cv2.
The idea:
find out the total frames
if frames is null, then call the writer of cv2 and generate a temporary copy of the video clip.
mix the audio from the original video with the copy.
replace the original video and delete copy.
then call the function clip = mp.VideoFileClip("/home/test/"+file)
Clarification: Since OpenCV VideoWriter does not encode audio, the new copy will not contain audio, so it would be necessary to extract the audio from the original video and then mix it with the copy, before replacing it with the original video.
You must import cv2
import cv2
And then add something like this in your code before the evaluation:
cap = cv2.VideoCapture("/home/test/"+file)
frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
fps = int(cap.get(cv2.CAP_PROP_FPS))
print(f'Checking Video {count} Frames {frames} fps: {fps}')
This will surely return 0 frames but should return at least framerate (fps).
Now we can set the evaluation to avoid the error and handle it making a temp video:
if frames == 0:
print(f'No frames data in video {file}, trying to convert this video..')
writer = cv2.VideoWriter("/home/test/fixVideo.avi", cv2.VideoWriter_fourcc(*'DIVX'), int(cap.get(cv2.CAP_PROP_FPS)),(int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)),int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))))
while True:
ret, frame = cap.read()
if ret is True:
writer.write(frame)
else:
cap.release()
print("Stopping video writer")
writer.release()
writer = None
break
Mix the audio from the original video with the copy. I have created a function for this:
def mix_audio_to_video(pathVideoInput, pathVideoNonAudio, pathVideoOutput):
videoclip = VideoFileClip(pathVideoInput)
audioclip = videoclip.audio
new_audioclip = CompositeAudioClip([audioclip])
videoclipNew = VideoFileClip(pathVideoNonAudio)
videoclipNew.audio = new_audioclip
videoclipNew.write_videofile(pathVideoOutput)
mix_audio_to_video("/home/test/"+file, "/home/test/fixVideo.avi", "/home/test/fixVideo.mp4")
replace the original video and delete copys:
os.replace("/home/test/fixVideo.mp4", "/home/test/"+file)
I had the same problem and I have found the solution.
I don't know why but if we enter the path in this method path = r'<path>' instead of ("F:\\path") we get no error.
Just click on the
C:\Users\gladi\AppData\Local\Programs\Python\Python311\Lib\site-packages\moviepy\video\io\ffmpeg_reader.py
and delete the the code and add this one
Provided by me in GITHUB - https://github.com/dudegladiator/Edited-ffmpeg-for-moviepy
clip1=VideoFileClip('path')
c=clip1.duration
print(c)

Categories