Spaces:
Sleeping
Sleeping
rosyvs
commited on
Commit
·
daa6f25
1
Parent(s):
c4ab5b6
Add log_tools to use for implementing better logging to the Gradio console TODO at a future date
Browse filesPrint ongoing FFMPEG output to command line for debugging
Remove vcodec and acodec specifications for conversion of webm to !wav as it was taking ages to transcode opus to aac / vp9 --> h264
- app.py +23 -10
- log_tools.py +58 -0
- utils.py +50 -26
app.py
CHANGED
|
@@ -3,9 +3,7 @@ import re
|
|
| 3 |
import threading
|
| 4 |
import time
|
| 5 |
from pathlib import Path
|
| 6 |
-
|
| 7 |
import random
|
| 8 |
-
|
| 9 |
import gradio as gr
|
| 10 |
|
| 11 |
from utils import (HHMMSS_to_sec, molly_xlsx_to_table, convert_and_trim_video,
|
|
@@ -43,12 +41,18 @@ def trim_video_helper(input_file, output_file, start_time, end_time):
|
|
| 43 |
# Trim the video
|
| 44 |
print("...start trimming")
|
| 45 |
output_file = convert_and_trim_video(input_file.name, output_file, start_time, end_time)
|
|
|
|
|
|
|
|
|
|
| 46 |
print("...finished trimming")
|
| 47 |
return output_file
|
| 48 |
|
| 49 |
def convert_video_helper(input_file, output_file, output_format):
|
| 50 |
# convert video
|
| 51 |
output_file = convert_and_trim_video(input_file.name, output_file)
|
|
|
|
|
|
|
|
|
|
| 52 |
print("...finished converting")
|
| 53 |
return output_file
|
| 54 |
|
|
@@ -78,21 +82,23 @@ def trim_video_vtr(input_file, output_format):
|
|
| 78 |
output_file = set_output_file(input_file, output_format, output_folder, insert_string)
|
| 79 |
|
| 80 |
# write the start time, and end time to a txt file
|
| 81 |
-
|
| 82 |
-
print("
|
| 83 |
-
with open(
|
| 84 |
f.write(f"{start_time}\n")
|
| 85 |
f.write(f"{end_time}\n")
|
| 86 |
|
| 87 |
# Trim the video
|
| 88 |
output_file = trim_video_helper(input_file, output_file, start_time, end_time)
|
| 89 |
-
|
|
|
|
|
|
|
| 90 |
# delete threading
|
| 91 |
print("Done trimming. Deleting files...")
|
| 92 |
-
path_to_delete = [input_file.name, output_file,
|
| 93 |
threading.Thread(target=delete_files, args=([path_to_delete])).start()
|
| 94 |
|
| 95 |
-
return output_file,
|
| 96 |
except Exception as e:
|
| 97 |
gr.Error(f"Error: {str(e)}")
|
| 98 |
return f"Error: {e}"
|
|
@@ -109,7 +115,9 @@ def trim_video_wt(input_file, input_transcript, output_format, start_time, end_t
|
|
| 109 |
|
| 110 |
# Trim the video
|
| 111 |
output_file = trim_video_helper(input_file, output_file, start_time, end_time)
|
| 112 |
-
|
|
|
|
|
|
|
| 113 |
# convert transcript
|
| 114 |
path = input_transcript.name
|
| 115 |
output_transcript = convert_transcript_helper(path, output_transcript)
|
|
@@ -149,7 +157,9 @@ def trim_video(input_file, output_format, start_time, end_time):
|
|
| 149 |
|
| 150 |
# Trim the video
|
| 151 |
output_file = trim_video_helper(input_file, output_file, start_time, end_time)
|
| 152 |
-
|
|
|
|
|
|
|
| 153 |
# Remove files after 10 minutes for security
|
| 154 |
print("Done trimming. Deleting files...")
|
| 155 |
path_to_delete = [input_file.name, output_file]
|
|
@@ -169,6 +179,9 @@ def convert_video(input_file, output_format):
|
|
| 169 |
insert_string = 'converted')
|
| 170 |
# Convert video
|
| 171 |
output_file = convert_video_helper(input_file, output_file, output_format)
|
|
|
|
|
|
|
|
|
|
| 172 |
print(f"...created output file: {output_file}")
|
| 173 |
# remove file after 10 minutes for security
|
| 174 |
print("Done converting. Deleting files...")
|
|
|
|
| 3 |
import threading
|
| 4 |
import time
|
| 5 |
from pathlib import Path
|
|
|
|
| 6 |
import random
|
|
|
|
| 7 |
import gradio as gr
|
| 8 |
|
| 9 |
from utils import (HHMMSS_to_sec, molly_xlsx_to_table, convert_and_trim_video,
|
|
|
|
| 41 |
# Trim the video
|
| 42 |
print("...start trimming")
|
| 43 |
output_file = convert_and_trim_video(input_file.name, output_file, start_time, end_time)
|
| 44 |
+
if not output_file:
|
| 45 |
+
print("...trimming failed due to FFMPEG error")
|
| 46 |
+
return None
|
| 47 |
print("...finished trimming")
|
| 48 |
return output_file
|
| 49 |
|
| 50 |
def convert_video_helper(input_file, output_file, output_format):
|
| 51 |
# convert video
|
| 52 |
output_file = convert_and_trim_video(input_file.name, output_file)
|
| 53 |
+
if not output_file:
|
| 54 |
+
print("...converting failed due to FFMPEG error")
|
| 55 |
+
return None
|
| 56 |
print("...finished converting")
|
| 57 |
return output_file
|
| 58 |
|
|
|
|
| 82 |
output_file = set_output_file(input_file, output_format, output_folder, insert_string)
|
| 83 |
|
| 84 |
# write the start time, and end time to a txt file
|
| 85 |
+
time_file = f"{os.getcwd()}/results/{audio_base_name}_start_end_time.txt"
|
| 86 |
+
print("time_file: ", time_file)
|
| 87 |
+
with open(time_file, "w") as f:
|
| 88 |
f.write(f"{start_time}\n")
|
| 89 |
f.write(f"{end_time}\n")
|
| 90 |
|
| 91 |
# Trim the video
|
| 92 |
output_file = trim_video_helper(input_file, output_file, start_time, end_time)
|
| 93 |
+
if not output_file:
|
| 94 |
+
gr.Error(f"Error: FFMPEG failed to trim the video.")
|
| 95 |
+
return None, None
|
| 96 |
# delete threading
|
| 97 |
print("Done trimming. Deleting files...")
|
| 98 |
+
path_to_delete = [input_file.name, output_file, time_file]
|
| 99 |
threading.Thread(target=delete_files, args=([path_to_delete])).start()
|
| 100 |
|
| 101 |
+
return output_file, time_file
|
| 102 |
except Exception as e:
|
| 103 |
gr.Error(f"Error: {str(e)}")
|
| 104 |
return f"Error: {e}"
|
|
|
|
| 115 |
|
| 116 |
# Trim the video
|
| 117 |
output_file = trim_video_helper(input_file, output_file, start_time, end_time)
|
| 118 |
+
if not output_file:
|
| 119 |
+
gr.Error(f"Error: FFMPEG failed to trim the video.")
|
| 120 |
+
return None, None
|
| 121 |
# convert transcript
|
| 122 |
path = input_transcript.name
|
| 123 |
output_transcript = convert_transcript_helper(path, output_transcript)
|
|
|
|
| 157 |
|
| 158 |
# Trim the video
|
| 159 |
output_file = trim_video_helper(input_file, output_file, start_time, end_time)
|
| 160 |
+
if not output_file:
|
| 161 |
+
gr.Error(f"Error: FFMPEG failed to trim the video.")
|
| 162 |
+
return None
|
| 163 |
# Remove files after 10 minutes for security
|
| 164 |
print("Done trimming. Deleting files...")
|
| 165 |
path_to_delete = [input_file.name, output_file]
|
|
|
|
| 179 |
insert_string = 'converted')
|
| 180 |
# Convert video
|
| 181 |
output_file = convert_video_helper(input_file, output_file, output_format)
|
| 182 |
+
if not output_file:
|
| 183 |
+
gr.Error(f"Error: FFMPEG failed to convert the video.")
|
| 184 |
+
return None
|
| 185 |
print(f"...created output file: {output_file}")
|
| 186 |
# remove file after 10 minutes for security
|
| 187 |
print("Done converting. Deleting files...")
|
log_tools.py
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# https://github.com/gradio-app/gradio/issues/2362
|
| 2 |
+
import re
|
| 3 |
+
import sys
|
| 4 |
+
|
| 5 |
+
class Logger:
|
| 6 |
+
def __init__(self, filename):
|
| 7 |
+
|
| 8 |
+
self.filename = f"{LOG_DIR}{filename}"
|
| 9 |
+
self.terminal = sys.stdout
|
| 10 |
+
self.reset_logs()
|
| 11 |
+
self.log = open(self.filename, "w")
|
| 12 |
+
self.flush()
|
| 13 |
+
|
| 14 |
+
def write(self, message):
|
| 15 |
+
self.terminal.write(message)
|
| 16 |
+
self.log.write(message)
|
| 17 |
+
|
| 18 |
+
def flush(self):
|
| 19 |
+
self.terminal.flush()
|
| 20 |
+
self.log.flush()
|
| 21 |
+
|
| 22 |
+
def isatty(self):
|
| 23 |
+
return False
|
| 24 |
+
|
| 25 |
+
def reset_logs(self):
|
| 26 |
+
with open(self.filename, 'w') as file:
|
| 27 |
+
file.truncate(0)
|
| 28 |
+
|
| 29 |
+
def read_logs(self):
|
| 30 |
+
sys.stdout.flush()
|
| 31 |
+
|
| 32 |
+
# Read the entire content of the log file
|
| 33 |
+
with open(self.filename, "r") as f:
|
| 34 |
+
log_content = f.readlines()
|
| 35 |
+
|
| 36 |
+
# Filter out lines containing null characters
|
| 37 |
+
log_content = [line for line in log_content if '\x00' not in line]
|
| 38 |
+
|
| 39 |
+
# Define the regex pattern for the progress bar
|
| 40 |
+
progress_pattern = re.compile(r'\[.*\] \d+\.\d+%')
|
| 41 |
+
|
| 42 |
+
# Find lines matching the progress bar pattern
|
| 43 |
+
progress_lines = [line for line in log_content if
|
| 44 |
+
progress_pattern.search(line) and " - Completed!\n" not in line]
|
| 45 |
+
|
| 46 |
+
# If there are multiple progress bars, keep only the last one in recent_lines
|
| 47 |
+
if progress_lines:
|
| 48 |
+
valid_content = [line for line in log_content if line not in progress_lines]
|
| 49 |
+
if log_content[-1] == progress_lines[-1]:
|
| 50 |
+
valid_content.append(progress_lines[-1].strip("\n"))
|
| 51 |
+
else:
|
| 52 |
+
valid_content = log_content
|
| 53 |
+
|
| 54 |
+
# Get the latest 30 lines
|
| 55 |
+
recent_lines = valid_content[-30:]
|
| 56 |
+
|
| 57 |
+
# Return the joined recent lines
|
| 58 |
+
return ''.join(recent_lines)
|
utils.py
CHANGED
|
@@ -4,7 +4,7 @@ import os
|
|
| 4 |
import re
|
| 5 |
import subprocess
|
| 6 |
from pathlib import Path
|
| 7 |
-
|
| 8 |
import gradio as gr
|
| 9 |
import pandas as pd
|
| 10 |
|
|
@@ -15,6 +15,11 @@ logging.basicConfig(filename=f'{os.getcwd()}/logs/logfile.log', level=logging.IN
|
|
| 15 |
format='%(asctime)s - %(levelname)s - %(message)s')
|
| 16 |
logging.info('Starting the application...')
|
| 17 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 18 |
def sort_transcript(file_path: str, save_path: str) -> str:
|
| 19 |
"""
|
| 20 |
Sort the rows of a transcript file by start time.
|
|
@@ -216,8 +221,12 @@ def convert_and_trim_video(media_in, media_out, start=None, end=None):
|
|
| 216 |
|
| 217 |
if out_ext == '.wav':
|
| 218 |
if in_ext == '.webm':
|
| 219 |
-
command = [
|
| 220 |
-
'
|
|
|
|
|
|
|
|
|
|
|
|
|
| 221 |
|
| 222 |
else:
|
| 223 |
# convert to wav with standard format for audio models
|
|
@@ -232,38 +241,53 @@ def convert_and_trim_video(media_in, media_out, start=None, end=None):
|
|
| 232 |
'-ac', str(WAV_CHANNELS),
|
| 233 |
'-ar', str(WAV_SAMPLE_RATE),
|
| 234 |
media_out,
|
| 235 |
-
'-hide_banner', '-loglevel', '
|
| 236 |
|
| 237 |
else: # convert using copy codec
|
| 238 |
if in_ext == '.webm':
|
| 239 |
-
command = [
|
| 240 |
-
|
| 241 |
-
|
| 242 |
-
|
| 243 |
-
|
| 244 |
-
|
| 245 |
-
|
| 246 |
-
|
|
|
|
|
|
|
| 247 |
else: # not webm
|
| 248 |
-
command = [
|
| 249 |
-
|
| 250 |
-
|
| 251 |
-
|
| 252 |
-
|
| 253 |
-
|
| 254 |
-
|
|
|
|
| 255 |
|
| 256 |
# run the ffmpeg command
|
| 257 |
logging.info(f"FFMPEG command: {' '.join(command)}")
|
| 258 |
gr.Info(f"FFMPEG command: {' '.join(command)}", visible=False)
|
| 259 |
-
|
| 260 |
-
|
| 261 |
-
|
| 262 |
-
|
| 263 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 264 |
else:
|
| 265 |
-
logging.info(
|
| 266 |
-
|
|
|
|
| 267 |
|
| 268 |
except Exception as e:
|
| 269 |
print(f"Error converting video format: {e}")
|
|
|
|
| 4 |
import re
|
| 5 |
import subprocess
|
| 6 |
from pathlib import Path
|
| 7 |
+
import sys
|
| 8 |
import gradio as gr
|
| 9 |
import pandas as pd
|
| 10 |
|
|
|
|
| 15 |
format='%(asctime)s - %(levelname)s - %(message)s')
|
| 16 |
logging.info('Starting the application...')
|
| 17 |
|
| 18 |
+
|
| 19 |
+
def subprocess_run_verbose(cmd):
|
| 20 |
+
res = subprocess.check_call(cmd, stdout=sys.stdout, stderr=subprocess.STDOUT)
|
| 21 |
+
return res
|
| 22 |
+
|
| 23 |
def sort_transcript(file_path: str, save_path: str) -> str:
|
| 24 |
"""
|
| 25 |
Sort the rows of a transcript file by start time.
|
|
|
|
| 221 |
|
| 222 |
if out_ext == '.wav':
|
| 223 |
if in_ext == '.webm':
|
| 224 |
+
command = [
|
| 225 |
+
'ffmpeg', '-y',
|
| 226 |
+
'-i', media_in,
|
| 227 |
+
*trim_command,
|
| 228 |
+
media_out,
|
| 229 |
+
'-hide_banner', '-loglevel', 'info']
|
| 230 |
|
| 231 |
else:
|
| 232 |
# convert to wav with standard format for audio models
|
|
|
|
| 241 |
'-ac', str(WAV_CHANNELS),
|
| 242 |
'-ar', str(WAV_SAMPLE_RATE),
|
| 243 |
media_out,
|
| 244 |
+
'-hide_banner', '-loglevel', 'info']
|
| 245 |
|
| 246 |
else: # convert using copy codec
|
| 247 |
if in_ext == '.webm':
|
| 248 |
+
command = [
|
| 249 |
+
'ffmpeg', '-y',
|
| 250 |
+
'-i', media_in,
|
| 251 |
+
'-strict', '-2',
|
| 252 |
+
*trim_command,
|
| 253 |
+
'-c', 'copy',
|
| 254 |
+
# '-vcodec', 'h264',
|
| 255 |
+
# '-acodec', 'aac',
|
| 256 |
+
media_out,
|
| 257 |
+
'-hide_banner', '-loglevel', 'info']
|
| 258 |
else: # not webm
|
| 259 |
+
command = [
|
| 260 |
+
'ffmpeg',
|
| 261 |
+
'-y',
|
| 262 |
+
'-i', media_in,
|
| 263 |
+
*trim_command,
|
| 264 |
+
'-c','copy',
|
| 265 |
+
media_out,
|
| 266 |
+
'-hide_banner', '-loglevel', 'info']
|
| 267 |
|
| 268 |
# run the ffmpeg command
|
| 269 |
logging.info(f"FFMPEG command: {' '.join(command)}")
|
| 270 |
gr.Info(f"FFMPEG command: {' '.join(command)}", visible=False)
|
| 271 |
+
print(f"...FFMPEG command: {' '.join(command)}")
|
| 272 |
+
# process = subprocess.run(command, capture_output=True, text=True)
|
| 273 |
+
# if process.returncode != 0:
|
| 274 |
+
# logging.info(f"FFMPEG error: {process.stderr}")
|
| 275 |
+
# print(f"FFMPEG error: {process.stderr}")
|
| 276 |
+
# gr.Error(f"FFMPEG error: {process.stderr}")
|
| 277 |
+
# else:
|
| 278 |
+
# logging.info(process.stdout)
|
| 279 |
+
# print(f"...FFMPEG status: {process.stdout}")
|
| 280 |
+
return_code = subprocess_run_verbose(command)
|
| 281 |
+
print(f"FFMPEG return code: {return_code}")
|
| 282 |
+
if return_code != 0:
|
| 283 |
+
logging.info(f"FFMPEG error: {return_code}")
|
| 284 |
+
print(f"FFMPEG error: {return_code}")
|
| 285 |
+
gr.Error(f"FFMPEG error: {return_code}")
|
| 286 |
+
return None
|
| 287 |
else:
|
| 288 |
+
logging.info(f"...FFMPEG completed successfully...")
|
| 289 |
+
print(f"...FFMPEG completed successfully...")
|
| 290 |
+
return media_out
|
| 291 |
|
| 292 |
except Exception as e:
|
| 293 |
print(f"Error converting video format: {e}")
|