FrameEx:動画からフレーム画像を抽出

初めに

FrameEx:作ってみました ffmpeg.exe準備してください

プログラマ

import tkinter as tk
from tkinter import ttk, filedialog, messagebox
import subprocess
import threading
import os

class FrameEx:
    def __init__(self, root):
        self.root = root
        self.root.title('FrameEx Python')
        self.root.geometry('700x500')

        self.video_var = tk.StringVar()
        self.output_var = tk.StringVar()
        self.format_var = tk.StringVar(value='png')
        self.start_var = tk.StringVar()
        self.end_var = tk.StringVar()

        self.proc = None

        frm = ttk.Frame(root, padding=10)
        frm.pack(fill='both', expand=True)

        ttk.Label(frm, text='Video').grid(row=0,column=0,sticky='w')
        ttk.Entry(frm,textvariable=self.video_var,width=70).grid(row=0,column=1)
        ttk.Button(frm,text='Browse',command=self.select_video).grid(row=0,column=2)

        ttk.Label(frm,text='Output').grid(row=1,column=0,sticky='w')
        ttk.Entry(frm,textvariable=self.output_var,width=70).grid(row=1,column=1)
        ttk.Button(frm,text='Browse',command=self.select_output).grid(row=1,column=2)

        ttk.Label(frm,text='Format').grid(row=2,column=0,sticky='w')
        ttk.Combobox(frm,textvariable=self.format_var,values=['png','jpg'],state='readonly',width=10).grid(row=2,column=1,sticky='w')

        ttk.Label(frm,text='Start (HH:MM:SS)').grid(row=3,column=0,sticky='w')
        ttk.Entry(frm,textvariable=self.start_var,width=20).grid(row=3,column=1,sticky='w')

        ttk.Label(frm,text='End (HH:MM:SS)').grid(row=4,column=0,sticky='w')
        ttk.Entry(frm,textvariable=self.end_var,width=20).grid(row=4,column=1,sticky='w')

        ttk.Button(frm,text='Extract',command=self.start_extract).grid(row=5,column=1,sticky='w',pady=10)
        ttk.Button(frm,text='Stop',command=self.stop_extract).grid(row=5,column=1,padx=100,sticky='w')

        self.pb = ttk.Progressbar(frm,mode='indeterminate')
        self.pb.grid(row=6,column=0,columnspan=3,sticky='ew',pady=5)

        self.log = tk.Text(frm,height=18)
        self.log.grid(row=7,column=0,columnspan=3,sticky='nsew')

        frm.rowconfigure(7,weight=1)
        frm.columnconfigure(1,weight=1)

    def logmsg(self,msg):
        self.log.insert('end',msg+'\n')
        self.log.see('end')

    def select_video(self):
        f = filedialog.askopenfilename(filetypes=[('Videos','*.mp4 *.mov *.avi *.mkv *.wmv')])
        if f:
            self.video_var.set(f)

    def select_output(self):
        d = filedialog.askdirectory()
        if d:
            self.output_var.set(d)

    def start_extract(self):
        threading.Thread(target=self.extract,daemon=True).start()

    def extract(self):
        video = self.video_var.get()
        outdir = self.output_var.get()

        if not video or not outdir:
            messagebox.showerror('Error','Select video and output folder')
            return

        ext = self.format_var.get()
        base_name = os.path.splitext(os.path.basename(video))[0]
        pattern = os.path.join(outdir, f'{base_name}_%06d.{ext}')
        cmd = ['ffmpeg']

        if self.start_var.get().strip():
            cmd += ['-ss', self.start_var.get().strip()]

        cmd += ['-i', video]

        if self.end_var.get().strip():
            cmd += ['-to', self.end_var.get().strip()]

        cmd += ['-start_number', '1', pattern]

        self.logmsg(' '.join(cmd))
        self.pb.start()

        try:
            self.proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True)
            for line in self.proc.stdout:
                self.logmsg(line.rstrip())
            self.proc.wait()
            self.logmsg('Finished')
        except Exception as e:
            self.logmsg(str(e))
        finally:
            self.pb.stop()
            self.proc = None

    def stop_extract(self):
        if self.proc:
            self.proc.kill()
            self.logmsg('Stopped')

root = tk.Tk()
app = FrameEx(root)
root.mainloop()

Python

Posted by eightban