유튜브 자막 추출후 구글 번역기로 한국어 번역 텍스트 출력
라이브러리 설치:
npm install youtube-captions-scraper @vitalets/google-translate-api http-proxy-agent https-proxy-agent got
1) proxyLists.ts
import fs from 'fs/promises'; import got from 'got'; import path from 'path'; const FILE_PATH = path.join(__dirname, 'proxies.txt'); export async function getFastestProxy(): Promise<string | null> { try { const today = new Date().toISOString().split('T')[0]; // YYYY-MM-DD let proxies: string[] = []; // 파일이 존재하는지 체크 try { const fileData = await fs.readFile(FILE_PATH, 'utf-8'); const [fileDate, ...fileProxies] = fileData.split('\n').filter(Boolean); if (fileDate === today) { console.log('✅ 오늘 날짜 프록시 캐시 사용'); proxies = fileProxies; } else { console.log('???? 날짜 다름, 새로 프록시 가져오기'); proxies = await fetchAndSaveProxies(today); } } catch (err) { console.log('???? 파일 없음 또는 에러, 새로 프록시 가져오기'); proxies = await fetchAndSaveProxies(today); } if (proxies.length === 0) { throw new Error('프록시가 없습니다.'); } // 랜덤 프록시 선택 const randomIndex = Math.floor(Math.random() * proxies.length); const proxy = proxies[randomIndex].trim(); // 랜덤으로 선택된 프록시 console.log('✅ 선택된 랜덤 프록시:', proxy); return `http://${proxy}`; } catch (error) { console.error('❌ 프록시 가져오기 실패:', error); return null; } } async function fetchAndSaveProxies(today: string): Promise<string[]> { const response = await got('https://api.proxyscrape.com/v2/?request=getproxies&protocol=http&timeout=3000&country=all&ssl=all&anonymity=all'); const proxies = response.body.split('\n').filter(Boolean); if (proxies.length === 0) { throw new Error('받아온 프록시 리스트가 비어있습니다.'); } const fileContent = [today, ...proxies].join('\n'); await fs.writeFile(FILE_PATH, fileContent, 'utf-8'); console.log('???? 새 프록시 파일 저장 완료'); return proxies; }
2)service.ts
import type { Core } from "@strapi/strapi"; import { getSubtitles } from 'youtube-captions-scraper'; import { translate } from '@vitalets/google-translate-api'; import { HttpProxyAgent } from 'http-proxy-agent'; import { HttpsProxyAgent } from "https-proxy-agent"; import got from "got"; import { getFastestProxy } from "./proxyLists"; /** * ???? youtube-captions-scraper 라이브러리를 사용한 번역 * ???? service.ts 복사 붙여 넣기 * @param videoId * @param lang * @returns */ // 첫 문장이 한국어인지 확인하는 함수 function isKorean(text: string): boolean { const koreanRegex = /[ㄱ-ㅎ|ㅏ-ㅣ|가-힣]/; return koreanRegex.test(text); } async function getYouTubeTranscript(videoId: string, lang: string = 'ko'): Promise<string | null> { const languages = ['ko', 'en']; // 우선 한국어, 그다음 영어 자막으로 시도 for (let language of languages) { try { const transcriptItems = await getSubtitles({ videoID: videoId, lang: language // 각 언어로 자막을 가져옵니다. }); if (transcriptItems.length > 0) { return transcriptItems.map(item => item.text).join(' '); } else { console.log(`${language} 자막이 없습니다.`); } } catch (error) { // console.error(`${language} 자막을 가져오는 중 오류가 발생했습니다.`, error); } } return null; // 자막을 찾지 못한 경우 null 반환 } const service = ({ strapi }: { strapi: Core.Strapi }) => ({ async getYoutubeTranscript(videoId: string) { const youtubeIdRegex = /^[a-zA-Z0-9_-]{11}$/; const isValid = youtubeIdRegex.test(videoId); if (!isValid) { return { error: "Invalid video ID", data: null }; } try { const transcript = await getYouTubeTranscript(videoId); if (!transcript) { return { error: "대본을 가져오는 데 실패했습니다.", data: null }; } let korTranscript =transcript; // 첫 번째 문장이 한국어인지 확인 if (isKorean(transcript.split(' ')[0])) { console.log("✅ 첫 문장이 한국어로 확인되어 프록시 없이 바로 반환합니다."); return korTranscript; } try { //???? 여기에서 번역을 수행 console.log("????프록시 설정:"); //const agent = new HttpProxyAgent('http://103.152.112.162:80'); const proxyUrl = await getFastestProxy(); if (proxyUrl) { console.log("✅ 사용 프록시:", proxyUrl); const agent = proxyUrl.startsWith('https') ? new HttpsProxyAgent(proxyUrl) : new HttpProxyAgent(proxyUrl); const customGot = got.extend({ agent: { http: agent, https: agent, }, }); const { text } = await translate(transcript, { to: 'ko', fetchOptions: customGot }); korTranscript = text; console.log("✅ 사용 프록시 적용 번역 ????????????????:", korTranscript); } } catch (error) { console.log("⚠️ 빠른 프록시를 찾지 못했습니다. 프록시 없이 번역 시도합니다."); try { const { text } = await translate(transcript, { to: 'ko' }); korTranscript = text; } catch (error) { console.log(" 오류 --원본::") korTranscript =transcript; } } return korTranscript; } catch (error) { return { error: "대본을 가져오는 중 오류가 발생했습니다: " + error, data: null }; } }, }); export default service;
댓글 ( 0)
댓글 남기기