Skip to content

Instantly share code, notes, and snippets.

@etodd
Last active August 1, 2026 15:43
Show Gist options
  • Select an option

  • Save etodd/0bca3def141dfc6883feecb14f6393e1 to your computer and use it in GitHub Desktop.

Select an option

Save etodd/0bca3def141dfc6883feecb14f6393e1 to your computer and use it in GitHub Desktop.
YouTube VTT cleaning script
#!/usr/bin/env python3
# Forked and improved version of https://github.com/anandiamy/Batch-Single-Clean-Youtube-Vtt/blob/main/single_clean.py
# Remove duplicated lines from a .vtt file generated by youtube-dl when
# downloading auto-subs from a Youtube video using the --write-auto-sub option
# This script only prints the lines so save the edited subs as:
#
# python this_script.py original_sub.vtt new_sub.vtt
import re
import sys
import html
# a subtitle is a timestamp line followed by one or more lines of text
# Find a line starting with a time stamp: 00:13:23 ...
TIMESTAMP_PATTERN = re.compile(r'^\d\d:\d\d:\d\d', re.M)
# Matches inline YouTube timestamps like:
# <00:00:01.680>
INLINE_TIMESTAMP_PATTERN = re.compile(r'<\d\d:\d\d:\d\d\.\d{3}>')
# Matches caption formatting tags like:
# <c> and </c>
CAPTION_TAG_PATTERN = re.compile(r'</?c>')
def clean_vtt_line(line):
"""Remove YouTube inline timestamps and caption formatting tags."""
line = INLINE_TIMESTAMP_PATTERN.sub('', line)
line = CAPTION_TAG_PATTERN.sub('', line)
line = html.unescape(line)
return line
def print_subtitle(output_file, timestamp, text, previous_text):
deduped = [line for line in text if line == '\n' or line not in previous_text]
if len([line for line in deduped if line.strip()]) == 0:
return
output_file.write(timestamp)
for t in deduped:
output_file.write(t)
def clean_vtt_content(input_file, output_file):
with open(input_file, 'r', encoding='utf-8') as f:
subtitle_timestamp = ''
subtitle_text = []
last_subtitle_text = []
for line in f:
line = clean_vtt_line(line)
if re.findall(TIMESTAMP_PATTERN, line):
print_subtitle(output_file, subtitle_timestamp, subtitle_text, last_subtitle_text)
last_subtitle_text = subtitle_text
subtitle_timestamp = line
subtitle_text = []
continue
subtitle_text.append(line)
print_subtitle(output_file, subtitle_timestamp, subtitle_text, last_subtitle_text)
if __name__ == "__main__":
try:
input_file = sys.argv[1]
output_file = sys.argv[2]
with open(output_file, 'w', encoding='utf-8') as out_f:
clean_vtt_content(input_file, out_f)
print(f"File successfully cleaned and saved to {output_file}")
except FileNotFoundError:
print("Error: Input file not found")
except Exception as e:
print(f"An error occurred: {str(e)}")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment