<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Kenny Shaw</title>
    <description>The latest articles on DEV Community by Kenny Shaw (@kennyshaw).</description>
    <link>https://dev.to/kennyshaw</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4039731%2Fe71ae3cd-cd11-493b-bf65-68ebb2744a72.jpg</url>
      <title>DEV Community: Kenny Shaw</title>
      <link>https://dev.to/kennyshaw</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kennyshaw"/>
    <language>en</language>
    <item>
      <title>How to Turn TikTok and YouTube Videos into SRT with One CLI Command</title>
      <dc:creator>Kenny Shaw</dc:creator>
      <pubDate>Sat, 01 Aug 2026 16:08:19 +0000</pubDate>
      <link>https://dev.to/kennyshaw/how-to-turn-tiktok-and-youtube-videos-into-srt-with-one-cli-command-4flh</link>
      <guid>https://dev.to/kennyshaw/how-to-turn-tiktok-and-youtube-videos-into-srt-with-one-cli-command-4flh</guid>
      <description>&lt;p&gt;Turning a public video into editable subtitles often means juggling a downloader, an audio converter, a speech-to-text model, and an SRT formatter. That is manageable once. It becomes tedious when the source is a TikTok link today, a YouTube URL tomorrow, and an Instagram Reel the next day.&lt;/p&gt;

&lt;p&gt;I wanted a workflow that starts with the link and ends with text or subtitles, without writing a new scraper for every platform. This tutorial shows the CLI workflow I use with &lt;a href="https://videosays.com/?utm_source=devto&amp;amp;utm_medium=referral&amp;amp;utm_campaign=cli_tutorial" rel="noopener noreferrer"&gt;Videosays&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the workflow produces
&lt;/h2&gt;

&lt;p&gt;From a supported public video link, you can request:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;plain transcript text&lt;/li&gt;
&lt;li&gt;timestamped timeline text&lt;/li&gt;
&lt;li&gt;SRT subtitles&lt;/li&gt;
&lt;li&gt;WebVTT subtitles&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The CLI supports public links and share text from sources including YouTube, TikTok, Instagram Reels, X, Douyin, Xiaohongshu, Bilibili, and Kuaishou. Availability still depends on whether the source video is publicly accessible and whether its audio can be processed.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Log in from the terminal
&lt;/h2&gt;

&lt;p&gt;You need Node.js 18 or newer. There is no global installation step:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx videosays login
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The command opens a browser authorization flow and stores the resulting API key locally in &lt;code&gt;~/.videosays&lt;/code&gt;. For CI or another non-interactive environment, you can also provide &lt;code&gt;VIDEOSAYS_API_KEY&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Transcribe a public video link
&lt;/h2&gt;

&lt;p&gt;Pass the video URL directly to the command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx videosays transcribe &lt;span class="s2"&gt;"https://www.tiktok.com/@creator/video/123456"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The default output is clean transcript text. You can also paste the complete share text copied from a social app; the CLI extracts a supported link from it.&lt;/p&gt;

&lt;p&gt;For YouTube, the workflow is identical:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx videosays transcribe &lt;span class="s2"&gt;"https://www.youtube.com/watch?v=VIDEO_ID"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each accepted transcription creates a task. Keep the returned task ID, especially for longer videos that may still be processing when the first command returns.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Export SRT subtitles
&lt;/h2&gt;

&lt;p&gt;Choose SRT with the &lt;code&gt;--format&lt;/code&gt; option:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx videosays transcribe &lt;span class="s2"&gt;"https://www.youtube.com/watch?v=VIDEO_ID"&lt;/span&gt; &lt;span class="nt"&gt;--format&lt;/span&gt; srt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the task is still running, retrieve it later:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx videosays status &lt;span class="s2"&gt;"TASK_ID"&lt;/span&gt; &lt;span class="nt"&gt;--format&lt;/span&gt; srt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;SRT is useful for video editors and publishing platforms because each subtitle block contains a sequence number, a start time, an end time, and the spoken text.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Use timeline or VTT output when needed
&lt;/h2&gt;

&lt;p&gt;For a readable timestamped transcript:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx videosays transcribe &lt;span class="s2"&gt;"VIDEO_URL"&lt;/span&gt; &lt;span class="nt"&gt;--format&lt;/span&gt; timeline
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For web players that expect WebVTT:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx videosays transcribe &lt;span class="s2"&gt;"VIDEO_URL"&lt;/span&gt; &lt;span class="nt"&gt;--format&lt;/span&gt; vtt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The four available formats are:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Format&lt;/th&gt;
&lt;th&gt;Best for&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;text&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;notes, search, summaries, and content repurposing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;timeline&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;reviewing what was said at a specific moment&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;srt&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;subtitle editing and common publishing workflows&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;vtt&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;HTML5 video players and web caption tracks&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  5. Let an AI agent run the same workflow
&lt;/h2&gt;

&lt;p&gt;The CLI also ships with a &lt;code&gt;SKILL.md&lt;/code&gt; package. In an agent environment that supports skills, you can install the public repository:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx skills add xwchris/videosays-agent-tools
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or give the agent this instruction:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Read https://videosays.com/SKILL.md, install the Videosays Skill if your environment supports skills, and help me transcribe this public video link.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is useful when the transcript is only the first step. An agent can obtain the text and then turn it into notes, chapters, a summary, or a content brief.&lt;/p&gt;

&lt;h2&gt;
  
  
  Practical considerations
&lt;/h2&gt;

&lt;p&gt;A few details matter in production:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Only process content you are allowed to use.&lt;/strong&gt; This workflow is for transcription and subtitle extraction, not for bypassing access controls or republishing someone else's video.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Expect platform variability.&lt;/strong&gt; A public URL can still be blocked by region, login requirements, deleted media, or source-platform changes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keep task IDs.&lt;/strong&gt; Longer jobs may require polling with the status command.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Choose the output format at retrieval time.&lt;/strong&gt; The same task can be retrieved as text, timeline, SRT, or VTT.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use batch commands for lists.&lt;/strong&gt; The CLI also includes batch creation, status, continuation, and cancellation commands.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://videosays.com/?utm_source=devto&amp;amp;utm_medium=referral&amp;amp;utm_campaign=cli_tutorial" rel="noopener noreferrer"&gt;Videosays website&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://videosays.com/docs?utm_source=devto&amp;amp;utm_medium=referral&amp;amp;utm_campaign=cli_tutorial" rel="noopener noreferrer"&gt;API and product documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.npmjs.com/package/videosays" rel="noopener noreferrer"&gt;Videosays CLI on npm&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/xwchris/videosays-agent-tools" rel="noopener noreferrer"&gt;Open-source agent tools and SKILL.md on GitHub&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The core idea is simple: keep the input as a video link and make transcript formatting an option, rather than building a different pipeline for every source platform.&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>ai</category>
      <category>cli</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
