<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/rss-style.xsl" type="text/xsl"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	    xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	     xmlns:dc="http://purl.org/dc/elements/1.1/"
	   xmlns:atom="http://www.w3.org/2005/Atom"
	     xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	  xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>
<channel>
	<title>subtitles &#8211; Terence Eden’s Blog</title>
	<atom:link href="https://shkspr.mobi/blog/tag/subtitles/feed/" rel="self" type="application/rss+xml" />
	<link>https://shkspr.mobi/blog</link>
	<description>Regular nonsense about tech and its effects 🙃</description>
	<lastBuildDate>Tue, 10 Sep 2024 07:07:19 +0000</lastBuildDate>
	<language>en-GB</language>
	<copyright>© Terence Eden. 🄯 CC BY-SA. See https://shkspr.mobi/blog/copyright-and-copyleft/</copyright>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.1.3</generator>

<image>
	<url>https://shkspr.mobi/blog/wp-content/uploads/2023/07/cropped-avatar-32x32.jpeg</url>
	<title>subtitles &#8211; Terence Eden’s Blog</title>
	<link>https://shkspr.mobi/blog</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title><![CDATA[Convert WebVTT to a Transcript using Python]]></title>
		<link>https://shkspr.mobi/blog/2018/09/convert-webvtt-to-a-transcript-using-python/</link>
					<comments>https://shkspr.mobi/blog/2018/09/convert-webvtt-to-a-transcript-using-python/#comments</comments>
				<dc:creator><![CDATA[Terence Eden]]></dc:creator>
		<pubDate>Mon, 10 Sep 2018 11:05:23 +0000</pubDate>
		<category><![CDATA[EMFCamp]]></category><category><![CDATA[HowTo]]></category><category><![CDATA[python]]></category><category><![CDATA[subtitles]]></category><category><![CDATA[YouTube]]></category>		<guid isPermaLink="false">https://shkspr.mobi/blog/?p=30341</guid>

					<description><![CDATA[I want to convert YouTube&#039;s auto-generated subtitles into a plain transcript. Why is this so hard?  This blog post gives a more detailed explanation than my answer to this StackOverflow question.  Here&#039;s what the subtitles look like when you view a video:   And here&#039;s what the code which generates those subtitles looks like:  00:00:00.930 --&#62; 00:00:03.080 align:start position:0% …]]></description>
										<content:encoded>&lt;p&gt;I want to convert YouTube's auto-generated subtitles into a plain transcript. Why is this so hard?&lt;/p&gt;

&lt;p&gt;This blog post gives a more detailed explanation than my answer to &lt;a href="https://stackoverflow.com/questions/51784232/how-do-i-convert-the-webvtt-format-to-plain-text"&gt;this StackOverflow question&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Here's what the subtitles look like when you view a video:
&lt;img src="https://shkspr.mobi/blog/wp-content/uploads/2018/09/YouTube-showing-subtitles.jpg" alt="YouTube showing subtitles." width="600" height="338" class="aligncenter size-full wp-image-30343"&gt;&lt;/p&gt;

&lt;p&gt;And here's what the code which generates those subtitles looks like:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-_"&gt;00:00:00.930 --&amp;gt; 00:00:03.080 align:start position:0%

and&amp;lt;00:00:01.230&amp;gt;&amp;lt;c&amp;gt; now&amp;lt;/c&amp;gt;&amp;lt;00:00:01.439&amp;gt;&amp;lt;c&amp;gt; can&amp;lt;/c&amp;gt;&amp;lt;00:00:01.709&amp;gt;&amp;lt;c&amp;gt; we&amp;lt;/c&amp;gt;&amp;lt;00:00:01.800&amp;gt;&amp;lt;c&amp;gt; have&amp;lt;/c&amp;gt;&amp;lt;c.colorCCCCCC&amp;gt;&amp;lt;00:00:01.920&amp;gt;&amp;lt;c&amp;gt; a&amp;lt;/c&amp;gt;&amp;lt;/c&amp;gt;&amp;lt;c.colorE5E5E5&amp;gt;&amp;lt;00:00:01.979&amp;gt;&amp;lt;c&amp;gt; round&amp;lt;/c&amp;gt;&amp;lt;00:00:02.370&amp;gt;&amp;lt;c&amp;gt; of&amp;lt;/c&amp;gt;&amp;lt;00:00:02.460&amp;gt;&amp;lt;c&amp;gt; applause&amp;lt;/c&amp;gt;&amp;lt;/c&amp;gt;

00:00:03.080 --&amp;gt; 00:00:03.090 align:start position:0%
and now can we have&amp;lt;c.colorCCCCCC&amp;gt; a&amp;lt;/c&amp;gt;&amp;lt;c.colorE5E5E5&amp;gt; round of applause
 &amp;lt;/c&amp;gt;

00:00:03.090 --&amp;gt; 00:00:04.849 align:start position:0%
and now can we have&amp;lt;c.colorCCCCCC&amp;gt; a&amp;lt;/c&amp;gt;&amp;lt;c.colorE5E5E5&amp;gt; round of applause
for&amp;lt;/c&amp;gt;&amp;lt;c.colorCCCCCC&amp;gt;&amp;lt;00:00:03.120&amp;gt;&amp;lt;c&amp;gt; Terrence&amp;lt;/c&amp;gt;&amp;lt;00:00:03.629&amp;gt;&amp;lt;c&amp;gt; Edwards&amp;lt;/c&amp;gt;&amp;lt;00:00:03.899&amp;gt;&amp;lt;c&amp;gt; and&amp;lt;/c&amp;gt;&amp;lt;00:00:04.170&amp;gt;&amp;lt;c&amp;gt; his&amp;lt;/c&amp;gt;&amp;lt;/c&amp;gt;&amp;lt;c.colorE5E5E5&amp;gt;&amp;lt;00:00:04.200&amp;gt;&amp;lt;c&amp;gt; talk&amp;lt;/c&amp;gt;&amp;lt;00:00:04.529&amp;gt;&amp;lt;c&amp;gt; the&amp;lt;/c&amp;gt;&amp;lt;/c&amp;gt;

00:00:04.849 --&amp;gt; 00:00:04.859 align:start position:0%
for&amp;lt;c.colorCCCCCC&amp;gt; Terrence Edwards and his&amp;lt;/c&amp;gt;&amp;lt;c.colorE5E5E5&amp;gt; talk the
 &amp;lt;/c&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;WTF? You're looking at &lt;a href="https://www.w3.org/TR/webvtt1/"&gt;WebVTT&lt;/a&gt; - Web Video Text Tracks Format - this allows words to be displayed as they're said. Each sentence and word is given a time-code and a position, colours are also possible to identify multiple speakers.  It's great for subtitles, but it is lousy if all you want to do is read a transcript.&lt;/p&gt;

&lt;p&gt;So, how do we convert the above to something like:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;and now can we have a round of applause for Terrence Edwards and his talk the connected house of horrors&lt;/p&gt;&lt;/blockquote&gt;

&lt;h2 id="python-the-quick-and-dirty-way"&gt;&lt;a href="https://shkspr.mobi/blog/2018/09/convert-webvtt-to-a-transcript-using-python/#python-the-quick-and-dirty-way"&gt;Python - the quick and dirty way&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;Using the &lt;a href="https://webvtt-py.readthedocs.io"&gt;open source WebVTT-PY&lt;/a&gt; Python library, we can directly get the raw text of each line of the subtitles&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-python"&gt;import webvtt
vtt = webvtt.read('subtitles-en.vtt')

vtt[0].text
' \nand now can we have a round of applause'
vtt[1].text
'and now can we have a round of applause\n '
vtt[2].text
'and now can we have a round of applause\nfor Terrence Edwards and his talk the'
vtt[3].text
'for Terrence Edwards and his talk the\n '
vtt[4].text
'for Terrence Edwards and his talk the\nconnected house of horrors good'
vtt[5].text
'connected house of horrors good\n '
vtt[6].text
'connected house of horrors good\nafternoon'
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Manually looking through the text, we can see that the 2nd element has the first complete sentence, then the 6th. Starting at 2, we can increment by 4 and grab elements 6, 10, 14, etc to build up a transcript. Does that work?&lt;/p&gt;

&lt;p&gt;Yes! This is what happens if we &lt;a href="https://docs.python.org/3/library/functions.html?highlight=slice#slice"&gt;slice the array&lt;/a&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-python"&gt;sub = vtt[2::4]

sub[0].text
'and now can we have a round of applause\nfor Terrence Edwards and his talk the'
sub[1].text
'connected house of horrors good\nafternoon'
sub[2].text
'AMF thank you so much for for coming\nhere my name is Terrence Eaton I need to'
sub[3].text
'tell you three things about this talk so\nthe first thing is that this does'
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;But are we sure that will work for all the subtitles? Or even for the entirety of this subtitle file?&lt;/p&gt;

&lt;h2 id="python-the-hard-way"&gt;&lt;a href="https://shkspr.mobi/blog/2018/09/convert-webvtt-to-a-transcript-using-python/#python-the-hard-way"&gt;Python the hard way&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;Let's take a look again at the first 4 subtitle entries.&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-_"&gt;vtt[0].text
' \nand now can we have a round of applause'
vtt[1].text
'and now can we have a round of applause\n '
vtt[2].text
'and now can we have a round of applause\nfor Terrence Edwards and his talk the'
vtt[3].text
'for Terrence Edwards and his talk the\n '
vtt[4].text
'for Terrence Edwards and his talk the\nconnected house of horrors good'
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We can split those double lines using&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-_"&gt;vtt[2].text.splitlines()
['and now can we have a round of applause', 'for Terrence Edwards and his talk the']
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Let's create a new array. Add all the lines split by &lt;code&gt;\n&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-python"&gt;lines = []
for line in vtt:
    lines.extend(line.text.strip().splitlines())
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Which gives us:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-_"&gt;&amp;gt;&amp;gt;&amp;gt; lines[0]
'and now can we have a round of applause'
&amp;gt;&amp;gt;&amp;gt; lines[1]
'and now can we have a round of applause'
&amp;gt;&amp;gt;&amp;gt; lines[2]
'and now can we have a round of applause'
&amp;gt;&amp;gt;&amp;gt; lines[3]
'for Terrence Edwards and his talk the'
&amp;gt;&amp;gt;&amp;gt; lines[4]
'for Terrence Edwards and his talk the'
&amp;gt;&amp;gt;&amp;gt; lines[5]
'for Terrence Edwards and his talk the'
&amp;gt;&amp;gt;&amp;gt; lines[6]
'connected house of horrors good'
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And now, to de-duplicate them:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-python"&gt;transcript = ""
previous = None
for line in lines:
    if line == previous:
       continue
    transcript += " " + line
    previous = line
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id="putting-it-all-together"&gt;&lt;a href="https://shkspr.mobi/blog/2018/09/convert-webvtt-to-a-transcript-using-python/#putting-it-all-together"&gt;Putting it all together&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;Ta-da!&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-python"&gt;import webvtt
vtt = webvtt.read('subtitles.vtt')
transcript = ""

lines = []
for line in vtt:
    lines.extend(line.text.strip().splitlines())

previous = None
for line in lines:
    if line == previous:
       continue
    transcript += " " + line
    previous = line

print(transcript)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;One thing to note is that there is &lt;em&gt;no&lt;/em&gt; punctuation. So it's not as good as a proper transcription.&lt;/p&gt;
&lt;img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=30341&amp;amp;HTTP_REFERER=RSS" alt="" width="1" height="1" loading="eager"&gt;</content:encoded>
					
					<wfw:commentRss>https://shkspr.mobi/blog/2018/09/convert-webvtt-to-a-transcript-using-python/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
			</item>
	</channel>
</rss>
