Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

TypeError: 'VideoFileClip' object is not subscriptable

I’m trying to make this application that will let you merge video clips together, however, when I try to merge two clips, I get this error: TypeError: 'VideoFileClip' object is not iterable. moreover, when I want to merge more than 2 clips, let’s say 3 clips, I get this error:
TypeError: 'VideoFileClip' object is not subscriptable. Any help will be appreciated.

Full error, when 2 video clips given:

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Users\Totenkopf\AppData\Local\Programs\Python\Python38\lib\tkinter\__init__.py", line 1883, in __call__
    return self.func(*args)
  File "D:/Python Projects/Windows/VideoMerger/main.py", line 80, in merge_vid
    final_clip = concatenate_videoclips(clip1, clip2)
  File "D:\Python Projects\Windows\VideoMerger\venv\lib\site-packages\moviepy\video\compositing\concatenate.py", line 71, in concatenate_videoclips
    tt = np.cumsum([0] + [c.duration for c in clips])
TypeError: 'VideoFileClip' object is not iterable

Full error when more than 2 clips given:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Users\Totenkopf\AppData\Local\Programs\Python\Python38\lib\tkinter\__init__.py", line 1883, in __call__
    return self.func(*args)
  File "D:/Python Projects/Windows/VideoMerger/main.py", line 87, in merge_vid
    final_clip = concatenate_videoclips(clip1, clip2, clip3)
  File "D:\Python Projects\Windows\VideoMerger\venv\lib\site-packages\moviepy\video\compositing\concatenate.py", line 67, in concatenate_videoclips
    l = [[v, transition] for v in clips[:-1]]
TypeError: 'VideoFileClip' object is not subscriptable

Code:

def open_location():

global filename_splitted
filename = askopenfilename()
filename_ext = os.path.splitext(filename)
filename_splitted = str(filename_ext).split('/')[4].split(".")[0].split(',')[0].split("'")[0]
filename_ext_split = filename_ext[1][1:]

if len(filename) > 1 and filename_ext_split == "mp4":
    path_url.config(text=filename_splitted, fg="green")

else:
    messagebox.showwarning(title="oops", message="No video given!")
    path_url.config(text="Please specify a file (mp4)!", fg="red")

return filename_splitted


def merge_vid():

    number_of_videos = box.get()
    if number_of_videos <= "1":
        messagebox.showwarning(title="Warning", message="Please specify how many videos you want to merge.")

    elif number_of_videos == "2":
        clip1 = VideoFileClip(f"{open_location()}.mp4")
        clip2 = VideoFileClip(f"{open_location()}.mp4")
        final_clip = concatenate_videoclips(clip1, clip2)
        final_clip.write_videofile('Final.mp4', codec="libx264")

    elif number_of_videos == "3":
        clip1 = VideoFileClip(f"{open_location()}.mp4")
        clip2 = VideoFileClip(f"{open_location()}.mp4")
        clip3 = VideoFileClip(f"{open_location()}.mp4")
        final_clip = concatenate_videoclips(clip1, clip2, clip3)
        final_clip.write_videofile('Final.mp4', codec="libx264")

    elif number_of_videos == "4":
        clip1 = VideoFileClip(f"{open_location()}.mp4")
        clip2 = VideoFileClip(f"{open_location()}.mp4")
        clip3 = VideoFileClip(f"{open_location()}.mp4")
        clip4 = VideoFileClip(f"{open_location()}.mp4")
        final_clip = concatenate_videoclips(clip1, clip2, clip3, clip4)
        final_clip.write_videofile('Final.mp4', codec="libx264")

Here’s the entire code in case anyone want to try it:

import tkinter

from moviepy.editor import *
from tkinter import *
from tkinter import messagebox
from tkinter import ttk
from tkinter import filedialog
import threading
import requests
import os
from tkinter.filedialog import askopenfilename


# import subprocess

# Converting video file types.
# subprocess.call("ffmpeg -i Z1.mov -q:v 0 Z1mp4.mp4", shell=True)
# subprocess.call("ffmpeg -i Z2.mov -q:v 0 Z2mp4.mp4", shell=True)
# subprocess.call("ffmpeg -i Z2.mov -q:v 0 Z3mp4.mp4", shell=True)
def prog_bar():
    progressbar = Tk()
    progressbar.geometry("555x33+600+100")
    progressbar.title("Downloading ffmpeg, please wait...")
    pb = ttk.Progressbar(progressbar, orient='horizontal', mode='determinate')
    pb.pack(expand=True, fill=tkinter.BOTH, side=tkinter.TOP)
    pb.start(11)
    progressbar.after(60000, message2)
    progressbar.after(90000, progressbar.destroy)
    progressbar.mainloop()

def message2():
    messagebox.showinfo(title="Download Completed", message="Download completed. Please restart the app.")

def download_ffmpeg():
    r = requests.get("https://www.dropbox.com/s/ur8miwz54us8ruc/ffmpeg.exe?dl=1", allow_redirects=True)
    open('C:/ffmpeg.exe', 'wb').write(r.content)
if os.path.exists("C:/ffmpeg.exe"):
    os.environ["IMAGEIO_FFMPEG_EXE"] = r"C:\ffmpeg.exe"

else:
    # threading.Thread(target=message1).start()
    threading.Thread(target=prog_bar).start()
    threading.Thread(target=download_ffmpeg).start()
    start_time = threading.Timer(33, message2)
    # start_time.start()
    # os.environ["IMAGEIO_FFMPEG_EXE"] = rf"{directory}\ffmpeg"
    os.environ["IMAGEIO_FFMPEG_EXE"] = r"C:\ffmpeg.exe"

def space():
    space = Label(text="", bg="black")
    space.pack()

def open_location():

    global filename_splitted
    filename = askopenfilename()
    filename_ext = os.path.splitext(filename)
    filename_splitted = str(filename_ext).split('/')[4].split(".")[0].split(',')[0].split("'")[0]
    filename_ext_split = filename_ext[1][1:]

    if len(filename) > 1 and filename_ext_split == "mp4":
        path_url.config(text=filename_splitted, fg="green")

    else:
        messagebox.showwarning(title="oops", message="No video given!")
        path_url.config(text="Please specify a file (mp4)!", fg="red")

    return filename_splitted


def merge_vid():

    number_of_videos = box.get()
    if number_of_videos <= "1":
        messagebox.showwarning(title="Warning", message="Please specify how many videos you want to merge.")

    elif number_of_videos == "2":
        clip1 = VideoFileClip(f"{open_location()}.mp4")
        clip2 = VideoFileClip(f"{open_location()}.mp4")
        final_clip = concatenate_videoclips(clip1, clip2)
        final_clip.write_videofile('Final.mp4', codec="libx264")

    elif number_of_videos == "3":
        clip1 = VideoFileClip(f"{open_location()}.mp4")
        clip2 = VideoFileClip(f"{open_location()}.mp4")
        clip3 = VideoFileClip(f"{open_location()}.mp4")
        final_clip = concatenate_videoclips(clip1, clip2, clip3)
        final_clip.write_videofile('Final.mp4', codec="libx264")

    elif number_of_videos == "4":
        clip1 = VideoFileClip(f"{open_location()}.mp4")
        clip2 = VideoFileClip(f"{open_location()}.mp4")
        clip3 = VideoFileClip(f"{open_location()}.mp4")
        clip4 = VideoFileClip(f"{open_location()}.mp4")
        final_clip = concatenate_videoclips(clip1, clip2, clip3, clip4)
        final_clip.write_videofile('Final.mp4', codec="libx264")



# def start_merge():
#         merge_vid()

def put_music():
    # audio = AudioFileClip("Music.mp3")
    # video1 = VideoFileClip("Final.mp4")
    # final = video1.set_audio(audio)
    # final.write_videofile("output.mp4")
    pass



root = Tk()

space()
space()

# root.iconbitmap("yt.ico")
root.title("Video Editor")
root.geometry("350x350")
root.columnconfigure(0, weight=1)
root.config(bg="black")

# space()
# path_btn = Button(root, width=11, height=2, bg="#CC1B25", fg="white", text="Select Video", command=open_location)
# path_btn.pack()

space()
space()
space()
label = Label(root, text="How many videos do you want to merge:", bg="black", fg="white", font=("jost", 9, "bold"))
label.pack()

EntryVar = StringVar()
box = Entry(root, width=7, textvariable=EntryVar)
box.pack()

space()

merge_btn = Button(root, width=27, height=3, bg="green", fg="white", text="Choose and Merge Videos", command=merge_vid)
merge_btn.pack()

space()
space()

# start_merge_btn = Button(root, width=27, height=3, bg="green", fg="white", text="Start Merge", command=start_merge)
# start_merge_btn.pack()

path_url = Label(root, text="", fg="red", bg="black", font=("jost", 9, "bold"))
path_url.pack()






root.mainloop()

>Solution :

Please read the moviepy docs for function concatenate_videoclips(clips, ..), especially about positional parameter clips:

clips
A list of video clips which must all have their duration
attributes set.

Following this, you should pass a list like [clip1, clip2] when invoking this method like this:

clip1 = VideoFileClip(f"{open_location()}.mp4")
clip2 = VideoFileClip(f"{open_location()}.mp4")
final_clip = concatenate_videoclips( [clip1, clip2] )  # both clips inside a list

See also the video concatenation example in the guide Mixing clips — MoviePy 1.0.2 documentation.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading