diff --git a/scripts/ffmpegusage.txt b/scripts/ffmpegusage.txt new file mode 100644 index 0000000..9dbf748 --- /dev/null +++ b/scripts/ffmpegusage.txt @@ -0,0 +1,28 @@ +ffmpeg -hwaccel cuda -i pulse_raw_aac.mp4 -vf "ass=pulse.ass" -acodec copy pulse_sub_aac.mp4 + +ffmpeg -hwaccel cuda -i pulse_raw_flac.mkv -vf "ass=pulse.ass" -c:v h264_nvenc -acodec copy pulse_sub_flac.mkv + +ffmpeg -hwaccel cuda -loop 1 -i pulse.png -i pulse.wav -c:v h264_nvenc -r 60 -c:a flac -compression_level 12 -pix_fmt yuv420p -shortest pulse.mkv + +ffmpeg -hwaccel cuda -loop 1 -i pulse.png -i pulse_192.mp3 -c:v h264_nvenc -r 60 -c:a aac -b:a 320k -pix_fmt yuv420p -shortest pulse.mp4 + +Get-ChildItem -Filter *.mp4 | ForEach-Object { + $name = $_.BaseName + & 'ffmpeg' -i "$name.mp4" -vn -ar 44100 -ac 2 -b:a 320k "$name.mp3" +} + +ffmpeg -i input_video.mp4 -vn -ar 44100 -ac 2 -q:a 0 -b:a 320k output_audio.mp3 + + +# --- Pulse PV: mux real audio into the Remotion render (no video re-encode) --- +# pulse-pv-project/out/pulseraw.mp4 is video-only; copy its video stream as-is +# and add pulse.wav. -c:v copy = instant + lossless. Feeds the ass=... step. + +# AAC (mp4), 320k: +ffmpeg -i pulse_raw.mp4 -i pulse.wav -map 0:v:0 -map 1:a:0 -c:v copy -c:a aac -b:a 320k -shortest pulse_raw_aac.mp4 + +# FLAC (mkv): +ffmpeg -i pulse_raw.mp4 -i pulse.wav -map 0:v:0 -map 1:a:0 -c:v copy -c:a flac -compression_level 12 -shortest pulse_raw_flac.mkv + + + diff --git a/scripts/lrc2srt.py b/scripts/lrc2srt.py new file mode 100644 index 0000000..17b8213 --- /dev/null +++ b/scripts/lrc2srt.py @@ -0,0 +1,67 @@ +import re +import sys +import os +from datetime import timedelta + +def format_timestamp(timestamp): + hours, remainder = divmod(timestamp.total_seconds(), 3600) + minutes, seconds = divmod(remainder, 60) + milliseconds = timestamp.microseconds // 1000 + return f"{int(hours):02d}:{int(minutes):02d}:{int(seconds):02d},{int(milliseconds):03d}" + +def lrc_to_srt(lrc_filename, srt_filename): + with open(lrc_filename, 'r', encoding='utf-8') as lrc_file: + lrc_content = lrc_file.readlines() + + srt_content = [] + subtitle_counter = 1 + previous_end_time = None + + for i, line in enumerate(lrc_content): + match = re.match(r'\[(\d{2}):(\d{2})\.(\d{2})\](.*)', line) + ## Explanation to the regex: + ## \[ (\d{2}) : (\d{2}) \. (\d{2}) \] (.*) + ## bracket minutes (2 digits) colon seconds (2 digits) dot millisecs (2 digits) bracket lyrical line (can be blank) + if match: + print(f'debug: matched line {line.strip()}') + start_minutes = int(match.group(1)) + start_seconds = int(match.group(2)) + start_milliseconds = int(match.group(3)) * 10 + print(f'matched text: {match.group(4)}') + + start_time = timedelta(minutes=start_minutes, seconds=start_seconds, milliseconds=start_milliseconds) + if len(srt_content) > 0: + # srt_content[-1] += f"{format_timestamp(start_time - timedelta(milliseconds=1))}\n" + srt_content[-1] += f"{format_timestamp(start_time)}\n" + srt_content.append(f"{subtitle_text}\n\n") + + srt_content.append(f"{subtitle_counter}\n") + srt_content.append(f"{format_timestamp(start_time)} --> ") + + subtitle_text = match.group(4).strip() + subtitle_counter += 1 + previous_end_time = start_time + + if previous_end_time is not None: + srt_content[-1] += f"{format_timestamp(previous_end_time)}\n" + srt_content.append(f"{subtitle_text}\n\n") + + + with open(srt_filename, 'w', encoding='utf-8') as srt_file: + srt_file.writelines(srt_content) + + print(f"Conversion from LRC to SRT completed. SRT file saved as '{srt_filename}'.") + +if __name__ == "__main__": + if not(len(sys.argv) == 3 or len(sys.argv) == 2): + print("Usage: python lrc2srt.py ") + print("or: python lrc2srt.py ") + print("If no output file name is supplied, the input file name will be used by default.") + else: + lrc_filename = sys.argv[1] + if len(sys.argv) == 3: + srt_filename = sys.argv[2] + else: + raw_filename, ext = os.path.splitext(lrc_filename) + srt_filename = raw_filename + '.srt' + lrc_to_srt(lrc_filename, srt_filename) \ No newline at end of file