You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript转TypeScript遇阻:Promise重构问题求助

问题:将YouTube字幕抓取脚本从JavaScript转TypeScript的Promise异步处理问题

我正尝试将一段可用的JavaScript字幕抓取脚本转换为TypeScript,但在重构Promise异步部分时遇到困难。原JavaScript代码已验证功能正常,但不确定如何将getUrlSrtSubtitles函数的Promise部分重构为可运行的TypeScript代码。

原JavaScript代码

var youtubeCaptionsScraper = require("youtube-captions-scraper")

function srtTimestamp(seconds) {
    var $milliseconds = seconds*1000;
    
    $seconds = Math.floor($milliseconds / 1000);
    $minutes = Math.floor($seconds / 60);
    $hours = Math.floor($minutes / 60);
    $milliseconds = $milliseconds % 1000;
    $seconds = $seconds % 60;
    $minutes = $minutes % 60;
    return ($hours < 10 ? '0' : '') + $hours + ':'
         + ($minutes < 10 ? '0' : '') + $minutes + ':'
         + ($seconds < 10 ? '0' : '') + $seconds + ','
         + ($milliseconds < 100 ? '0' : '') + ($milliseconds < 10 ? '0' : '') + $milliseconds;
}

function inputToSRT(srtCount, sub_in) {
  return srtCount + "\n" + srtTimestamp(sub_in.start) + " --> " + srtTimestamp(sub_in.dur) + "\n" + sub_in.text + "\n\n";
}
  
async function getUrlSrtSubtitles(url, language) {
   await youtubeCaptionsScraper.getSubtitles({
      videoID: url.split("v=")[1].split("&")[0], // youtube video id
      lang: language
    }).then(captions => {
        console.log(captions);
        // formating captions to srt text format
        srtCount = 0;
        srtString = '';
        for (var i=0; i<captions.length; i++) {
          srtString = srtString + inputToSRT(++srtCount, captions[i]);
        }

        console.log(srtString);
        return srtString;
    });
}

var url = "https://www.youtube.com/watch?v=7wnfj-b-wp4";
getUrlSrtSubtitles(url, 'en')

目前编写的TypeScript代码

src/types.ts

export interface SubCaptions {
  start: string;
  dur: string;
  text: string;
}

src/utils.ts

const youtubeCaptionsScraper = require("youtube-captions-scraper"); // youtubeCaptionsScraper
import {SubCaptions} from "./types";

///////////////////////////////////////////////////////
// youtubeCaptionsScraper functions
///////////////////////////////////////////////////////

export function srtTimestamp(seconds: number): string {
    
    var milliseconds = seconds * 1000;
    seconds = Math.floor(milliseconds / 1000);
    var minutes = Math.floor(seconds / 60);
    var hours = Math.floor(minutes / 60);
    milliseconds = milliseconds % 1000;
    seconds = seconds % 60;
    minutes = minutes % 60;
    return (hours < 10 ? '0' : '') + hours + ':'
         + (minutes < 10 ? '0' : '') + minutes + ':'
         + (seconds < 10 ? '0' : '') + seconds + ','
         + (milliseconds < 100 ? '0' : '') + (milliseconds < 10 ? '0' : '') + milliseconds;
}

export function inputToSRT(srtCount: number, sub_in: SubCaptions) {
  return srtCount + "\n" + srtTimestamp(Number(sub_in.start)) + " --> " + srtTimestamp(Number(sub_in.dur)) + "\n" + sub_in.text + "\n\n";
}

export function getUrlCaptions(url: string, language:  string): Array<SubCaptions> {
  
  const captionsArray = youtubeCaptionsScraper.getSubtitles(
    {
      videoID: url.split("v=")[1].split("&")[0], // extract youtube video id
      lang: language
    }
  )

  return captionsArray 
}

export function getUrlSrtSubtitles(url: string, language:  string): string {

  const captionsArray = getUrlCaptions(url, language);

  // declare var
  var srtCount = 0;
  var srtString = '';

  // formating captions to srt text format
  for (var i=0; i<captionsArray.length; i++) {
    srtString = srtString + inputToSRT(++srtCount, captionsArray[i]);
  }

  console.log(srtString);

  return srtString;

}

解决方案

关键问题分析

  1. 类型定义错误:SubCaptions接口中start和dur应为number类型(原库返回数值而非字符串),无需额外转换。
  2. 异步函数处理不当:youtubeCaptionsScraper.getSubtitles返回Promise,需用async/await处理,不能直接同步返回结果。
  3. 结束时间计算错误:原JS中SRT的结束时间应为start + dur,而非直接使用dur。

修改后的完整代码

src/types.ts

export interface SubCaptions {
  start: number;
  dur: number;
  text: string;
}

src/utils.ts

import youtubeCaptionsScraper from "youtube-captions-scraper";
import { SubCaptions } from "./types";

export function srtTimestamp(seconds: number): string {
  const milliseconds = seconds * 1000;
  const totalSeconds = Math.floor(milliseconds / 1000);
  const minutes = Math.floor(totalSeconds / 60);
  const hours = Math.floor(minutes / 60);
  
  const remainingMs = milliseconds % 1000;
  const remainingSeconds = totalSeconds % 60;
  const remainingMinutes = minutes % 60;

  return `${hours.toString().padStart(2, '0')}:${remainingMinutes.toString().padStart(2, '0')}:${remainingSeconds.toString().padStart(2, '0')},${remainingMs.toString().padStart(3, '0')}`;
}

export function inputToSRT(srtCount: number, sub_in: SubCaptions): string {
  return `${srtCount}\n${srtTimestamp(sub_in.start)} --> ${srtTimestamp(sub_in.start + sub_in.dur)}\n${sub_in.text}\n\n`;
}

export async function getUrlCaptions(url: string, language: string): Promise<SubCaptions[]> {
  const videoId = url.split("v=")[1]?.split("&")[0];
  if (!videoId) {
    throw new Error("Invalid YouTube URL");
  }
  
  return youtubeCaptionsScraper.getSubtitles({
    videoID: videoId,
    lang: language
  });
}

export async function getUrlSrtSubtitles(url: string, language: string): Promise<string> {
  const captionsArray = await getUrlCaptions(url, language);
  
  let srtString = '';
  captionsArray.forEach((caption, index) => {
    srtString += inputToSRT(index + 1, caption);
  });

  console.log(srtString);
  return srtString;
}

核心修改说明

  • 修正类型定义,匹配原库返回的数据结构。
  • 将getUrlCaptions和getUrlSrtSubtitles改为异步函数,返回对应Promise类型,通过await处理异步操作。
  • 修复SRT结束时间计算逻辑,确保时间轴正确。
  • 使用padStart简化时间格式化代码,提升可读性。
  • 添加视频ID有效性校验,避免无效URL导致的错误。
  • 替换var为const/let,遵循TypeScript最佳实践。

内容的提问来源于stack exchange,提问作者logan schwartz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 20:45:33