Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import tkinter as tk
- from tkinter import filedialog, messagebox
- import subprocess
- import os
- import yt_dlp
- import sys
- import threading
- from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QLabel, QVBoxLayout, QWidget
- from PyQt5.QtCore import QThread, pyqtSignal, pyqtSlot
- class VideoToolApp:
- def __init__(self, root):
- self.root = root
- self.root.title("Najeeb Advanced Video Tool with FFmpeg")
- self.root.geometry("620x460")
- self.root.configure(bg='#4a4a4a')
- # Video File Path
- self.video_path = tk.StringVar()
- tk.Label(root, text="Video File Path:", bg='#1d1f21', fg='white').grid(row=0, column=0, padx=10, pady=10, sticky='e')
- tk.Entry(root, textvariable=self.video_path, width=50, bg='#282a2e', fg='white').grid(row=0, column=1, padx=10, pady=10)
- tk.Button(root, text="Browse", command=self.browse_file, bg='#373b41', fg='white').grid(row=0, column=2, padx=10, pady=10)
- # YouTube and Other URLs
- self.url = tk.StringVar()
- tk.Label(root, text="Video URL:", bg='#1d1f21', fg='white').grid(row=1, column=0, padx=10, pady=10, sticky='e')
- tk.Entry(root, textvariable=self.url, width=50, bg='#282a2e', fg='white').grid(row=1, column=1, padx=10, pady=10)
- tk.Button(root, text="Download", command=self.download_video, bg='#373b41', fg='white').grid(row=1, column=2, padx=10, pady=10)
- # IPTV URL
- self.iptv_url = tk.StringVar()
- tk.Label(root, text="IPTV URL:", bg='#1d1f21', fg='white').grid(row=2, column=0, padx=10, pady=10, sticky='e')
- tk.Entry(root, textvariable=self.iptv_url, width=50, bg='#282a2e', fg='white').grid(row=2, column=1, padx=10, pady=10)
- tk.Button(root, text="Capture", command=self.capture_iptv, bg='#373b41', fg='white').grid(row=2, column=2, padx=10, pady=10)
- # Start and End Time
- self.start_time = tk.StringVar(value="00:00:00")
- self.end_time = tk.StringVar(value="00:00:00")
- tk.Label(root, text="Start Time (HH:MM:SS):", bg='#1d1f21', fg='white').grid(row=3, column=0, padx=10, pady=10, sticky='e')
- tk.Entry(root, textvariable=self.start_time, width=20, bg='#282a2e', fg='white').grid(row=3, column=1, padx=10, pady=10, sticky='w')
- tk.Label(root, text="End Time (HH:MM:SS):", bg='#1d1f21', fg='white').grid(row=4, column=0, padx=10, pady=10, sticky='e')
- tk.Entry(root, textvariable=self.end_time, width=20, bg='#282a2e', fg='white').grid(row=4, column=1, padx=10, pady=10, sticky='w')
- # Output File Path
- self.output_path = tk.StringVar()
- tk.Label(root, text="Output File Path:", bg='#1d1f21', fg='white').grid(row=5, column=0, padx=10, pady=10, sticky='e')
- tk.Entry(root, textvariable=self.output_path, width=50, bg='#282a2e', fg='white').grid(row=5, column=1, padx=10, pady=10)
- tk.Button(root, text="Save As", command=self.save_as_file, bg='#373b41', fg='white').grid(row=5, column=2, padx=10, pady=10)
- # Frame Interval for Image Extraction
- self.frame_interval = tk.StringVar()
- tk.Label(root, text="Frame Interval (seconds):", bg='#1d1f21', fg='white').grid(row=6, column=0, padx=10, pady=10, sticky='e')
- tk.Entry(root, textvariable=self.frame_interval, width=20, bg='#282a2e', fg='white').grid(row=6, column=1, padx=10, pady=10, sticky='w')
- # Buttons for operations
- tk.Button(root, text="Cut Video", command=self.cut_video, bg='#cc0066', fg='white').grid(row=7, column=0, padx=10, pady=20)
- tk.Button(root, text="Merge Videos", command=self.merge_videos, bg='#4c9900', fg='white').grid(row=7, column=1, padx=10, pady=20)
- tk.Button(root, text="Convert Video", command=self.convert_video, bg='#cc6600', fg='white').grid(row=7, column=2, padx=10, pady=20)
- tk.Button(root, text="Extract Pictures", command=self.extract_pictures, bg='#660000', fg='white').grid(row=6, column=2, padx=10, pady=20)
- # Desktop Recorder Button
- tk.Button(root, text="Desktop Recorder", command=self.desktop_recorder, bg='#0066cc', fg='white').grid(row=4, column=2, padx=10, pady=20)
- def browse_file(self):
- file_path = filedialog.askopenfilename(filetypes=[("Video files", "*.*")])
- if file_path:
- self.video_path.set(file_path)
- def save_as_file(self):
- file_path = filedialog.asksaveasfilename(defaultextension=".mp4", filetypes=[("All files", "*.*")])
- if file_path:
- self.output_path.set(file_path)
- def download_video(self):
- url = self.url.get()
- start_time = self.start_time.get()
- end_time = self.end_time.get()
- if not url:
- messagebox.showerror("Error", "Video URL must be provided")
- return
- try:
- ydl_opts = {}
- with yt_dlp.YoutubeDL(ydl_opts) as ydl:
- info = ydl.extract_info(url, download=False)
- download_path = filedialog.asksaveasfilename(defaultextension=".mp4", initialfile=info.get('title', 'video'), filetypes=[("All files", "*.*")])
- if download_path:
- ydl_opts = {'outtmpl': download_path}
- with yt_dlp.YoutubeDL(ydl_opts) as ydl:
- ydl.download([url])
- messagebox.showinfo("Success", "Video downloaded successfully")
- self.video_path.set(download_path)
- if start_time != "00:00:00" or end_time != "00:00:00":
- self.cut_video()
- self.extract_pictures()
- except Exception as e:
- messagebox.showerror("Error", f"Failed to download video: {str(e)}")
- def capture_iptv(self):
- iptv_url = self.iptv_url.get()
- output_file = filedialog.asksaveasfilename(defaultextension=".mp4", filetypes=[("All files", "*.*")])
- if not iptv_url or not output_file:
- messagebox.showerror("Error", "IPTV URL and output file path must be provided")
- return
- try:
- subprocess.run(["ffmpeg", "-i", iptv_url, "-c", "copy", output_file], check=True)
- messagebox.showinfo("Success", "IPTV stream captured successfully")
- self.video_path.set(output_file)
- except subprocess.CalledProcessError as e:
- messagebox.showerror("Error", f"Failed to capture IPTV stream: {str(e)}")
- def cut_video(self):
- input_file = self.video_path.get()
- start_time = self.start_time.get()
- end_time = self.end_time.get()
- output_file = self.output_path.get()
- if not input_file or not start_time or not end_time or not output_file:
- messagebox.showerror("Error", "All fields must be filled")
- return
- try:
- subprocess.run(["ffmpeg", "-i", input_file, "-ss", start_time, "-to", end_time, "-c", "copy", output_file], check=True)
- messagebox.showinfo("Success", "Video cut successfully")
- except subprocess.CalledProcessError as e:
- messagebox.showerror("Error", f"Failed to cut video: {str(e)}")
- def merge_videos(self):
- files = filedialog.askopenfilenames(filetypes=[("Video files", "*.*")])
- if not files:
- return
- output_file = filedialog.asksaveasfilename(defaultextension=".mp4", filetypes=[("All files", "*.*")])
- if not output_file:
- return
- with open('file_list.txt', 'w') as file_list:
- for file in files:
- file_list.write(f"file '{file}'\n")
- try:
- subprocess.run(["ffmpeg", "-f", "concat", "-safe", "0", "-i", "file_list.txt", "-c", "copy", output_file], check=True)
- os.remove('file_list.txt')
- messagebox.showinfo("Success", "Videos merged successfully")
- except subprocess.CalledProcessError as e:
- os.remove('file_list.txt')
- messagebox.showerror("Error", f"Failed to merge videos: {str(e)}")
- def convert_video(self):
- input_file = self.video_path.get()
- output_file = self.output_path.get()
- if not input_file or not output_file:
- messagebox.showerror("Error", "Input and Output paths must be filled")
- return
- try:
- subprocess.run(["ffmpeg", "-i", input_file, output_file], check=True)
- messagebox.showinfo("Success", "Video converted successfully")
- except subprocess.CalledProcessError as e:
- messagebox.showerror("Error", f"Failed to convert video: {str(e)}")
- def extract_pictures(self):
- input_file = self.video_path.get()
- output_dir = filedialog.askdirectory()
- frame_interval = self.frame_interval.get()
- if not input_file or not output_dir or not frame_interval:
- messagebox.showerror("Error", "Video file, output directory, and frame interval must be provided")
- return
- try:
- subprocess.run(["ffmpeg", "-i", input_file, "-vf", f"fps=1/{frame_interval}", f"{output_dir}/frame%04d.png"], check=True)
- messagebox.showinfo("Success", "Pictures extracted successfully")
- except subprocess.CalledProcessError as e:
- messagebox.showerror("Error", f"Failed to extract pictures: {str(e)}")
- def desktop_recorder(self):
- def start_pyqt_recorder():
- ffmpeg_path = r'C:\CMDER\APP\ffmpeg.exe' # Update with your ffmpeg path
- app = QApplication(sys.argv)
- ex = PyQtApp(ffmpeg_path)
- ex.show()
- sys.exit(app.exec_())
- recorder_thread = threading.Thread(target=start_pyqt_recorder)
- recorder_thread.start()
- class Recorder(QThread):
- changeStatus = pyqtSignal(str)
- def __init__(self, ffmpeg_path):
- super().__init__()
- self.recording = False
- self.process = None
- self.ffmpeg_path = ffmpeg_path
- def run(self):
- self.recording = True
- command = [
- self.ffmpeg_path,
- '-y', # Overwrite output file if it exists
- '-f', 'gdigrab',
- '-framerate', '20',
- '-i', 'desktop', # Capture the entire desktop
- '-c:v', 'libx264',
- '-preset', 'ultrafast',
- 'output.mp4'
- ]
- try:
- self.process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
- self.changeStatus.emit("Recording started...")
- while self.recording:
- output = self.process.stderr.readline()
- if output == '' and self.process.poll() is not None:
- break
- if output:
- print(output.strip())
- if self.process.poll() is None:
- self.process.terminate()
- self.process.wait()
- self.changeStatus.emit("Recording stopped and saved to output.mp4.")
- except Exception as e:
- self.changeStatus.emit(f"Error: {e}")
- self.recording = False
- def stop_recording(self):
- self.recording = False
- if self.process and self.process.poll() is None:
- self.process.terminate()
- self.process.wait()
- class PyQtApp(QMainWindow):
- def __init__(self, ffmpeg_path):
- super().__init__()
- self.setWindowTitle("Desktop Video Recorder")
- self.setGeometry(100, 100, 400, 200)
- self.recorder = None
- self.ffmpeg_path = ffmpeg_path
- self.initUI()
- def initUI(self):
- self.status_label = QLabel("Press Start to begin recording the desktop.", self)
- self.status_label.resize(400, 50)
- self.start_button = QPushButton("Start Recording", self)
- self.start_button.clicked.connect(self.start_recording)
- self.stop_button = QPushButton("Stop Recording", self)
- self.stop_button.clicked.connect(self.stop_recording)
- self.stop_button.setEnabled(False)
- layout = QVBoxLayout()
- layout.addWidget(self.status_label)
- layout.addWidget(self.start_button)
- layout.addWidget(self.stop_button)
- container = QWidget()
- container.setLayout(layout)
- self.setCentralWidget(container)
- def start_recording(self):
- self.recorder = Recorder(self.ffmpeg_path)
- self.recorder.changeStatus.connect(self.updateStatus)
- self.recorder.start()
- self.start_button.setEnabled(False)
- self.stop_button.setEnabled(True)
- def stop_recording(self):
- if self.recorder:
- self.recorder.stop_recording()
- self.recorder.wait()
- self.stop_button.setEnabled(False)
- self.start_button.setEnabled(True)
- @pyqtSlot(str)
- def updateStatus(self, message):
- self.status_label.setText(message)
- print(message) # Print to console for debugging
- if __name__ == "__main__":
- root = tk.Tk()
- app = VideoToolApp(root)
- root.mainloop()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement