ar08 commited on
Commit
266909b
·
verified ·
1 Parent(s): cb85a12

Upload 12 files

Browse files
genz/Dockerfile ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Use an official Python runtime as a parent image
2
+ FROM python:3.10-slim-buster
3
+
4
+ # Set the working directory in the Docker image
5
+ WORKDIR /app
6
+
7
+ # Install system dependencies
8
+ RUN apt-get update && apt-get install -y \
9
+ libgl1 \
10
+ libglib2.0-0 \
11
+ libzbar0 \
12
+ ffmpeg \
13
+ git \
14
+ && rm -rf /var/lib/apt/lists/*
15
+
16
+ RUN pip install uv
17
+
18
+ # Clone the repository
19
+ RUN git clone --depth 1 --branch master https://github.com/karaketir16/file2video.git /app
20
+
21
+ # Copy the current directory contents into the container at /app
22
+ #COPY . /app
23
+
24
+ RUN uv venv
25
+
26
+ # Install any needed packages specified in requirements.txt
27
+ RUN uv pip install --no-cache-dir -r requirements.txt
28
+
29
+ WORKDIR /data
30
+
31
+ # Run file2video.py when the container launches
32
+ ENTRYPOINT ["/app/.venv/bin/python", "/app/file2video.py", "--docker"]
33
+ CMD []
genz/__pycache__/checksum.cpython-310.pyc ADDED
Binary file (526 Bytes). View file
 
genz/__pycache__/decode_video.cpython-310.pyc ADDED
Binary file (2.69 kB). View file
 
genz/__pycache__/encode.cpython-310.pyc ADDED
Binary file (3.5 kB). View file
 
genz/__pycache__/youtube_decode.cpython-310.pyc ADDED
Binary file (1.15 kB). View file
 
genz/checksum.py ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import hashlib
2
+
3
+ def checksum(large_file):
4
+ """Calculate MD5 checksum for file."""
5
+ md5_object = hashlib.md5()
6
+ block_size = 128 * md5_object.block_size
7
+ with open(large_file, 'rb') as a_file:
8
+ chunk = a_file.read(block_size)
9
+ while chunk:
10
+ md5_object.update(chunk)
11
+ chunk = a_file.read(block_size)
12
+ return md5_object.hexdigest()
genz/convert.py ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from encode import create_video
2
+ from decode_video import decode
3
+ from youtube_decode import youtube_decode
4
+ import argparse
5
+ import sys
6
+
7
+ def enc_file(source_file, output_video):
8
+ print (f"Encoding {source_file} to {output_video}")
9
+ create_video(source_file, output_video)
10
+
11
+ def dec_video(source_video, destination_folder, docker_mode):
12
+ print (f"Decoding {source_video} to {destination_folder}")
13
+ decode(source_video, destination_folder)
14
+
15
+ def y_decode(video_url, destination_folder, docker_mode):
16
+ print (f"Decoding {video_url} to {destination_folder}")
17
+ youtube_decode(video_url, destination_folder)
18
+
19
+ def main():
20
+
21
+ # First, check if '--docker' is in the command line arguments
22
+ docker_mode = '--docker' in sys.argv
23
+ if docker_mode:
24
+ sys.argv.remove('--docker') # Remove it so it doesn't interfere with the main parser
25
+
26
+ docker_usage = """\
27
+ docker run --rm -v $(pwd):/data karaketir16/file2video [-h] [--encode source_file output_video]
28
+ [--decode source_video destination_folder]
29
+ [--youtube-decode youtube_url destination_folder]"""
30
+
31
+ if docker_mode:
32
+ parser = argparse.ArgumentParser(description="Program to encode files into videos and decode videos back to files.", usage=docker_usage)
33
+ else:
34
+ parser = argparse.ArgumentParser(description="Program to encode files into videos and decode videos back to files.")
35
+
36
+ # Optional argument for encoding
37
+ parser.add_argument("--encode", nargs=2, metavar=('source_file', 'output_video'),
38
+ help="Encode a file into a video: source_file output_video.mp4")
39
+
40
+ # Optional argument for decoding
41
+ parser.add_argument("--decode", nargs=2, metavar=('source_video', 'destination_folder'),
42
+ help="Decode a video to a file: source_video.mp4 destination_folder")
43
+
44
+ # Optional argument for YouTube video decoding
45
+ parser.add_argument("--youtube-decode", nargs=2, metavar=('youtube_url', 'destination_folder'),
46
+ help="Decode a video from a YouTube URL to a file: 'youtube_url' destination_folder")
47
+
48
+
49
+ args = parser.parse_args()
50
+
51
+ # Check which command is used and call the corresponding function
52
+ if args.encode:
53
+ enc_file(*args.encode)
54
+ elif args.decode:
55
+ dec_video(*args.decode, docker_mode)
56
+ elif args.youtube_decode:
57
+ y_decode(*args.youtube_decode, docker_mode)
58
+ else:
59
+ parser.print_help()
60
+
61
+ if __name__ == "__main__":
62
+ main()
genz/decode/usage.md ADDED
@@ -0,0 +1,114 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ python file2video.py --encode go.txt out.mp4
2
+ python file2video.py --decode out.mp4 ./
3
+ ```python
4
+ import cv2
5
+ import sys
6
+ import yt_dlp
7
+ import os
8
+ from datetime import datetime
9
+
10
+ from decode_video import decode_video
11
+
12
+ def youtube_decode(src, dest_folder):
13
+ base_filename = "downloaded_video"
14
+ timestamp = datetime.now().strftime("%Y%m%d%H%M%S")
15
+ output_file = f"{dest_folder}/{base_filename}_{timestamp}.mp4"
16
+
17
+ # Create a yt-dlp configuration to download the video
18
+ ydl_opts = {
19
+ 'format': 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best',
20
+ 'outtmpl': output_file,
21
+ 'noplaylist': True,
22
+ 'quiet': True,
23
+ 'merge_output_format': 'mp4', # Ensure the output is mp4 if separate streams are downloaded
24
+ }
25
+
26
+ # Use yt-dlp to download the video
27
+ with yt_dlp.YoutubeDL(ydl_opts) as ydl:
28
+ ydl.download([src])
29
+
30
+ # Check if the file is downloaded and exists
31
+ if os.path.exists(output_file):
32
+ # Open the downloaded video file using OpenCV
33
+ cap = cv2.VideoCapture(output_file)
34
+
35
+ # Read and process the video
36
+ decode_video(cap, dest_folder)
37
+ else:
38
+ print("Failed to download video.")
39
+ sys.exit(1)
40
+
41
+ if __name__ == '__main__':
42
+ if len(sys.argv) < 3:
43
+ print("Usage: python video2file.py \"https://video_url\" destination_folder")
44
+ sys.exit(1)
45
+
46
+ src = sys.argv[1]
47
+ dest_folder = sys.argv[2]
48
+ youtube_decode(src, dest_folder)
49
+
50
+ ```
51
+ ```python
52
+ from encode import create_video
53
+ from decode_video import decode
54
+ from youtube_decode import youtube_decode
55
+ import argparse
56
+ import sys
57
+
58
+ def enc_file(source_file, output_video):
59
+ print (f"Encoding {source_file} to {output_video}")
60
+ create_video(source_file, output_video)
61
+
62
+ def dec_video(source_video, destination_folder, docker_mode):
63
+ print (f"Decoding {source_video} to {destination_folder}")
64
+ decode(source_video, destination_folder)
65
+
66
+ def y_decode(video_url, destination_folder, docker_mode):
67
+ print (f"Decoding {video_url} to {destination_folder}")
68
+ youtube_decode(video_url, destination_folder)
69
+
70
+ def main():
71
+
72
+ # First, check if '--docker' is in the command line arguments
73
+ docker_mode = '--docker' in sys.argv
74
+ if docker_mode:
75
+ sys.argv.remove('--docker') # Remove it so it doesn't interfere with the main parser
76
+
77
+ docker_usage = """\
78
+ docker run --rm -v $(pwd):/data karaketir16/file2video [-h] [--encode source_file output_video]
79
+ [--decode source_video destination_folder]
80
+ [--youtube-decode youtube_url destination_folder]"""
81
+
82
+ if docker_mode:
83
+ parser = argparse.ArgumentParser(description="Program to encode files into videos and decode videos back to files.", usage=docker_usage)
84
+ else:
85
+ parser = argparse.ArgumentParser(description="Program to encode files into videos and decode videos back to files.")
86
+
87
+ # Optional argument for encoding
88
+ parser.add_argument("--encode", nargs=2, metavar=('source_file', 'output_video'),
89
+ help="Encode a file into a video: source_file output_video.mp4")
90
+
91
+ # Optional argument for decoding
92
+ parser.add_argument("--decode", nargs=2, metavar=('source_video', 'destination_folder'),
93
+ help="Decode a video to a file: source_video.mp4 destination_folder")
94
+
95
+ # Optional argument for YouTube video decoding
96
+ parser.add_argument("--youtube-decode", nargs=2, metavar=('youtube_url', 'destination_folder'),
97
+ help="Decode a video from a YouTube URL to a file: 'youtube_url' destination_folder")
98
+
99
+
100
+ args = parser.parse_args()
101
+
102
+ # Check which command is used and call the corresponding function
103
+ if args.encode:
104
+ enc_file(*args.encode)
105
+ elif args.decode:
106
+ dec_video(*args.decode, docker_mode)
107
+ elif args.youtube_decode:
108
+ y_decode(*args.youtube_decode, docker_mode)
109
+ else:
110
+ parser.print_help()
111
+
112
+ if __name__ == "__main__":
113
+ main()
114
+ ```
genz/decode_video.py ADDED
@@ -0,0 +1,103 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import cv2
2
+ import json
3
+ import os
4
+ import sys
5
+ import base64
6
+ import logging
7
+ from pyzbar import pyzbar
8
+ from tqdm import tqdm
9
+ from multiprocessing import Pool, cpu_count
10
+ from checksum import checksum
11
+
12
+ # Setup basic logging
13
+ logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
14
+
15
+ def apply_preprocessing(frame):
16
+ gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
17
+ _, threshold = cv2.threshold(gray, 128, 255, cv2.THRESH_BINARY)
18
+ return threshold
19
+
20
+ def read_barcode(preprocessed_frame):
21
+ barcodes = pyzbar.decode(preprocessed_frame)
22
+ for barcode in barcodes:
23
+ barcode_info = barcode.data.decode('utf-8')
24
+ return True, barcode_info
25
+ return False, None
26
+
27
+ def process_frame(frame):
28
+ preprocessed_frame = apply_preprocessing(frame)
29
+ success, data = read_barcode(preprocessed_frame)
30
+ if not success:
31
+ logging.warning("Failed to read QR code")
32
+ return None # Return None if no barcode is found
33
+ return data
34
+
35
+ def decode_video(cap, dest_folder):
36
+ if not os.path.exists(dest_folder):
37
+ os.makedirs(dest_folder)
38
+
39
+ total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
40
+ pbar = tqdm(total=total_frames, desc="Processing Frames")
41
+
42
+ ret, first_frame = cap.read()
43
+ if not ret:
44
+ logging.error("Cannot read first frame")
45
+ return
46
+
47
+ metadata = process_frame(first_frame)
48
+ if metadata is None:
49
+ logging.error("No QR code in first frame; cannot proceed")
50
+ return
51
+ meta_data = json.loads(metadata)
52
+ dest = os.path.join(dest_folder, meta_data["Filename"])
53
+ file = open(dest, "wb")
54
+
55
+ # Start worker processes
56
+ num_workers = cpu_count()
57
+
58
+ with Pool(num_workers) as pool:
59
+ while cap.isOpened():
60
+ frames = []
61
+ done = False
62
+ for _ in range(num_workers):
63
+ ret, frame = cap.read()
64
+ if ret:
65
+ frames.append(frame)
66
+ else:
67
+ done = True
68
+ break
69
+
70
+ datas = pool.map(process_frame, frames)
71
+
72
+ pbar.update(len(frames))
73
+
74
+ for data in datas:
75
+ file.write(base64.b64decode(data))
76
+
77
+ if done:
78
+ break
79
+
80
+
81
+ file.close()
82
+ cap.release()
83
+ pbar.close()
84
+
85
+ logging.info("Verify file integrity")
86
+ md5_sum = checksum(dest)
87
+ assert md5_sum == meta_data["Filehash"], "Data corrupted"
88
+ logging.info("File integrity verified: ")
89
+ logging.info(dest)
90
+
91
+ def decode(src, dest_folder):
92
+ cap = cv2.VideoCapture(src)
93
+ decode_video(cap, dest_folder)
94
+
95
+ if __name__ == '__main__':
96
+ if len(sys.argv) < 3:
97
+ logging.error("Usage: python script.py source_file.mp4 destination_folder")
98
+ sys.exit(1)
99
+ src = sys.argv[1]
100
+ dest_folder = sys.argv[2]
101
+
102
+ decode(src, dest_folder)
103
+
genz/encode.py ADDED
@@ -0,0 +1,125 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from itertools import islice
2
+ import os
3
+ import sys
4
+ import base64
5
+ import math
6
+ import json
7
+ import qrcode
8
+ import numpy as np
9
+ from multiprocessing import Pool, cpu_count
10
+ import av
11
+ from PIL import Image
12
+ from tqdm import tqdm
13
+
14
+ from checksum import checksum
15
+
16
+ # Constants
17
+ chunk_size = 500 # Adjust this as per the data capacity of QR codes and your specific requirements
18
+ frame_rate = 20.0
19
+ width = 1080
20
+ height = 1080
21
+
22
+ def read_in_chunks(file_object, chunk_size=1024):
23
+ """Generator to read a file piece by piece."""
24
+ while True:
25
+ data = file_object.read(chunk_size)
26
+ if not data:
27
+ break
28
+ yield data
29
+
30
+ def create_qr(data_str, box_size=10, error_correction_level=qrcode.constants.ERROR_CORRECT_L):
31
+ """Generate a QR code as a NumPy array from data string with specified box size and error correction level."""
32
+ qr = qrcode.QRCode(
33
+ version=1,
34
+ error_correction=error_correction_level,
35
+ box_size=box_size,
36
+ border=4,
37
+ )
38
+ qr.add_data(data_str)
39
+ img = qr.make_image(fill_color="black", back_color="white").convert('RGB')
40
+ pil_img = img.resize((width, height), Image.Resampling.NEAREST) # Use NEAREST for less interpolation blur
41
+ return np.array(pil_img)
42
+
43
+ def process_chunk(data):
44
+ """Encode data chunk into QR and return as image."""
45
+ return create_qr(base64.b64encode(data).decode('ascii'))
46
+
47
+ def encode_and_write_frames(frames, stream, container):
48
+ """Encode frames and write to video container."""
49
+ for frame in frames:
50
+ video_frame = av.VideoFrame.from_ndarray(frame, format='rgb24')
51
+ for packet in stream.encode(video_frame):
52
+ container.mux(packet)
53
+
54
+ def create_video(src, dest, read_file_lazy = False):
55
+ """Create video from source file using PyAV."""
56
+ md5_checksum = checksum(src)
57
+ file_stats = os.stat(src)
58
+ file_size = file_stats.st_size
59
+ chunk_count = math.ceil(file_size / chunk_size)
60
+
61
+ pbar = tqdm(total=chunk_count, desc="Generating Frames")
62
+
63
+ meta_data = {
64
+ "Filename": os.path.basename(src),
65
+ "ChunkCount": chunk_count,
66
+ "Filehash": md5_checksum,
67
+ "ConverterUrl": "https://github.com/karaketir16/file2video",
68
+ "ConverterVersion": "python_v1"
69
+ }
70
+
71
+ first_frame_data = json.dumps(meta_data, indent=4)
72
+ first_frame = create_qr(first_frame_data)
73
+
74
+ # Open output file
75
+ container = av.open(dest, mode='w')
76
+ stream = container.add_stream('h264', rate=frame_rate)
77
+ stream.width = width
78
+ stream.height = height
79
+ stream.pix_fmt = 'yuv420p'
80
+ stream.options = {'crf': '40'}
81
+
82
+ # Write the first frame
83
+ video_frame = av.VideoFrame.from_ndarray(first_frame, format='rgb24')
84
+ for packet in stream.encode(video_frame):
85
+ container.mux(packet)
86
+
87
+ # Process chunks in batches using multiprocessing
88
+ with open(src, 'rb') as f, Pool(cpu_count()) as pool:
89
+ entire_file = []
90
+ if not read_file_lazy:
91
+ entire_file = f.read()
92
+ i = 0
93
+ while True:
94
+
95
+ chunks = []
96
+
97
+ if read_file_lazy:
98
+ chunks = list(islice(read_in_chunks(f, chunk_size), cpu_count()))
99
+ else:
100
+ for _ in range(cpu_count()):
101
+ chunks.append(entire_file[i: i + chunk_size])
102
+ if not chunks[-1]: #empty
103
+ chunks.pop()
104
+ break
105
+ i = i + chunk_size
106
+ if not chunks:
107
+ break
108
+ frames = pool.map(process_chunk, chunks)
109
+ encode_and_write_frames(frames, stream, container)
110
+ pbar.update(len(frames))
111
+
112
+ pbar.close()
113
+
114
+ # Finalize the video file
115
+ for packet in stream.encode():
116
+ container.mux(packet)
117
+ container.close()
118
+
119
+ if __name__ == '__main__':
120
+ if len(sys.argv) < 3:
121
+ print("Usage: python file2video.py source_file output_file.mp4")
122
+ sys.exit(1)
123
+ src = sys.argv[1]
124
+ dest = sys.argv[2]
125
+ create_video(src, dest)
genz/usage.md ADDED
@@ -0,0 +1,114 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ python file2video.py --encode go.txt out.mp4
2
+ python file2video.py --decode out.mp4 ./
3
+ ```python
4
+ import cv2
5
+ import sys
6
+ import yt_dlp
7
+ import os
8
+ from datetime import datetime
9
+
10
+ from decode_video import decode_video
11
+
12
+ def youtube_decode(src, dest_folder):
13
+ base_filename = "downloaded_video"
14
+ timestamp = datetime.now().strftime("%Y%m%d%H%M%S")
15
+ output_file = f"{dest_folder}/{base_filename}_{timestamp}.mp4"
16
+
17
+ # Create a yt-dlp configuration to download the video
18
+ ydl_opts = {
19
+ 'format': 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best',
20
+ 'outtmpl': output_file,
21
+ 'noplaylist': True,
22
+ 'quiet': True,
23
+ 'merge_output_format': 'mp4', # Ensure the output is mp4 if separate streams are downloaded
24
+ }
25
+
26
+ # Use yt-dlp to download the video
27
+ with yt_dlp.YoutubeDL(ydl_opts) as ydl:
28
+ ydl.download([src])
29
+
30
+ # Check if the file is downloaded and exists
31
+ if os.path.exists(output_file):
32
+ # Open the downloaded video file using OpenCV
33
+ cap = cv2.VideoCapture(output_file)
34
+
35
+ # Read and process the video
36
+ decode_video(cap, dest_folder)
37
+ else:
38
+ print("Failed to download video.")
39
+ sys.exit(1)
40
+
41
+ if __name__ == '__main__':
42
+ if len(sys.argv) < 3:
43
+ print("Usage: python video2file.py \"https://video_url\" destination_folder")
44
+ sys.exit(1)
45
+
46
+ src = sys.argv[1]
47
+ dest_folder = sys.argv[2]
48
+ youtube_decode(src, dest_folder)
49
+
50
+ ```
51
+ ```python
52
+ from encode import create_video
53
+ from decode_video import decode
54
+ from youtube_decode import youtube_decode
55
+ import argparse
56
+ import sys
57
+
58
+ def enc_file(source_file, output_video):
59
+ print (f"Encoding {source_file} to {output_video}")
60
+ create_video(source_file, output_video)
61
+
62
+ def dec_video(source_video, destination_folder, docker_mode):
63
+ print (f"Decoding {source_video} to {destination_folder}")
64
+ decode(source_video, destination_folder)
65
+
66
+ def y_decode(video_url, destination_folder, docker_mode):
67
+ print (f"Decoding {video_url} to {destination_folder}")
68
+ youtube_decode(video_url, destination_folder)
69
+
70
+ def main():
71
+
72
+ # First, check if '--docker' is in the command line arguments
73
+ docker_mode = '--docker' in sys.argv
74
+ if docker_mode:
75
+ sys.argv.remove('--docker') # Remove it so it doesn't interfere with the main parser
76
+
77
+ docker_usage = """\
78
+ docker run --rm -v $(pwd):/data karaketir16/file2video [-h] [--encode source_file output_video]
79
+ [--decode source_video destination_folder]
80
+ [--youtube-decode youtube_url destination_folder]"""
81
+
82
+ if docker_mode:
83
+ parser = argparse.ArgumentParser(description="Program to encode files into videos and decode videos back to files.", usage=docker_usage)
84
+ else:
85
+ parser = argparse.ArgumentParser(description="Program to encode files into videos and decode videos back to files.")
86
+
87
+ # Optional argument for encoding
88
+ parser.add_argument("--encode", nargs=2, metavar=('source_file', 'output_video'),
89
+ help="Encode a file into a video: source_file output_video.mp4")
90
+
91
+ # Optional argument for decoding
92
+ parser.add_argument("--decode", nargs=2, metavar=('source_video', 'destination_folder'),
93
+ help="Decode a video to a file: source_video.mp4 destination_folder")
94
+
95
+ # Optional argument for YouTube video decoding
96
+ parser.add_argument("--youtube-decode", nargs=2, metavar=('youtube_url', 'destination_folder'),
97
+ help="Decode a video from a YouTube URL to a file: 'youtube_url' destination_folder")
98
+
99
+
100
+ args = parser.parse_args()
101
+
102
+ # Check which command is used and call the corresponding function
103
+ if args.encode:
104
+ enc_file(*args.encode)
105
+ elif args.decode:
106
+ dec_video(*args.decode, docker_mode)
107
+ elif args.youtube_decode:
108
+ y_decode(*args.youtube_decode, docker_mode)
109
+ else:
110
+ parser.print_help()
111
+
112
+ if __name__ == "__main__":
113
+ main()
114
+ ```
genz/youtube_decode.py ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import cv2
2
+ import sys
3
+ import yt_dlp
4
+ import os
5
+ from datetime import datetime
6
+
7
+ from decode_video import decode_video
8
+
9
+ def youtube_decode(src, dest_folder):
10
+ base_filename = "downloaded_video"
11
+ timestamp = datetime.now().strftime("%Y%m%d%H%M%S")
12
+ output_file = f"{dest_folder}/{base_filename}_{timestamp}.mp4"
13
+
14
+ # Create a yt-dlp configuration to download the video
15
+ ydl_opts = {
16
+ 'format': 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best',
17
+ 'outtmpl': output_file,
18
+ 'noplaylist': True,
19
+ 'quiet': True,
20
+ 'merge_output_format': 'mp4', # Ensure the output is mp4 if separate streams are downloaded
21
+ }
22
+
23
+ # Use yt-dlp to download the video
24
+ with yt_dlp.YoutubeDL(ydl_opts) as ydl:
25
+ ydl.download([src])
26
+
27
+ # Check if the file is downloaded and exists
28
+ if os.path.exists(output_file):
29
+ # Open the downloaded video file using OpenCV
30
+ cap = cv2.VideoCapture(output_file)
31
+
32
+ # Read and process the video
33
+ decode_video(cap, dest_folder)
34
+ else:
35
+ print("Failed to download video.")
36
+ sys.exit(1)
37
+
38
+ if __name__ == '__main__':
39
+ if len(sys.argv) < 3:
40
+ print("Usage: python video2file.py \"https://video_url\" destination_folder")
41
+ sys.exit(1)
42
+
43
+ src = sys.argv[1]
44
+ dest_folder = sys.argv[2]
45
+ youtube_decode(src, dest_folder)
46
+