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; }
解决方案
关键问题分析
- 类型定义错误:
SubCaptions接口中start和dur应为number类型(原库返回数值而非字符串),无需额外转换。 - 异步函数处理不当:
youtubeCaptionsScraper.getSubtitles返回Promise,需用async/await处理,不能直接同步返回结果。 - 结束时间计算错误:原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
相关产品推荐
相关产品推荐

