youtube-dl을 사용하여 자동 생성된 자막을 srt 형식으로 변환

youtube-dl을 사용하여 자동 생성된 자막을 srt 형식으로 변환

YouTube에서 생성된 자막을 다운로드하고 명령을 사용하여 srt 형식으로 변환하고 싶습니다. youtube-dl --write-auto-sub --sub-lang en --convert-subs=srt --skip-download <URL>.vtt 파일만 출력하고 srt로 변환하지 않습니다.

그러나 --skip-download제거되면 비디오, vtt 파일을 다운로드한 다음 마지막으로 vtt를 srt로 변환합니다.

동영상을 다운로드하지 않고 vtt 파일만 다운로드한 후 srt로 변환할 수 있는 방법이 있나요?

답변1

아마도 그 이유는 이 프로세스에서 배후에서 사용되는 ffmpeg가 "ffmpeg.exe -i path.vtt path.vtt.srt"와 같은 레코딩 요청을 직접 처리하지 않기 때문일 것입니다. 파일에 대한 스트림이 필요하고 이를 위해서는 비디오 파일이 필요합니다.

적어도 그러한 요청은 나에게는 효과가 없으며 인터넷에 유사한 예가 있음에도 불구하고 스트림이 없다고 보고합니다.

답변2

vtt를 srt로 변환하는 매우 간단한 명령줄 도구를 만들었습니다. 이는 매우 간단한 텍스트 처리(어휘 분석이나 토큰이 사용되지 않음)를 통해 작동하며 다음과 같은 텍스트에 대해 Youtube의 자동으로 전사된 자막에만 작동합니다.

WEBVTT 종류: captions 언어: en

00:00:01.740 --> 00:00:05.030 정렬:시작 위치:0%
없음<00:00:02.700>은<00:00:03.179> 불가능합니다...

여기에서 ZIP 파일로 다운로드할 수 있습니다.http://pececko.szm.com/@ VTT to SRT. 업데이트할 계획이 없으므로 이 코드를 공개 도메인으로 간주하시기 바랍니다. 이것이 누군가에게 유용할 수 있기를 바랍니다.

// C program to convert subtitles from VTT file to SRT file
// public domain
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXLINELEN 32767

int main(int argc,char** argv)
{
    FILE* fh;
    char filein[MAXLINELEN]; // = "test.vtt"
    char fileout[MAXLINELEN]; // = "test.srt"
    int i=0, j=0, k=0, l=0, m=0, pos=0;
    //float r=0;
    char **arr; // array of pointers to lines loaded to memory from file
    char *buffer, *line, *ptr;
    long numbytes;
    int erase=0, previousline=0; // booleans
    fputs("Convert Youtube's Autotranscribed VTT to SRT [build 2023-06-22]\nConverts .vtt files from youtube to .srt files.\nUsage: vtttosrt.exe [sourcesubtitles.vtt] [targetsubtitles.srt]\nPress Ctrl+C to abort.\n", stdout);
    if (argc>1){
        strcpy(filein, argv[1]);
    } else {
        printf("Enter input filename (*.vtt) :");
        fgets (filein, MAXLINELEN, stdin);
        filein[strlen(filein) - 1] = '\0';
    }
    k = strlen(filein);
    if (!k) {
        return 0;
    }
    if (k<=3 || (strstr(&filein[k-4],".vtt") == NULL)) {
        strcat(filein,".vtt"); //append missing extension
    }

    fh = fopen(filein, "r"); // Opening file in reading mode
    if (fh==NULL) {
        printf("File %s not found.\n",filein);
        return 1;
    }
 
    //printf("Loading file %s\n", filein);
    fseek(fh, 0L, SEEK_END);
    numbytes = ftell(fh); // Get the number of bytes
    fseek(fh, 0L, SEEK_SET);
    buffer = (char*)calloc(numbytes, sizeof(char)); 
    if(buffer == NULL) {
        fclose(fh);
        return 1;
    }
    fread(buffer, sizeof(char), numbytes, fh);
    fclose(fh);
    //printf("filesize is %d Bytes:\n%s\n",numbytes,buffer);

    arr = (char**)calloc(numbytes/4, sizeof(char));
    if(arr == NULL) {
        free(buffer);
        return 1;
    }
    pos=1;
    arr[0] = &buffer[0];
    for (i=0; i<numbytes; i++) {
        if (buffer[i]=='\n') {
            buffer[i]='\0';
            arr[pos++]=&buffer[i+1];
        }
    }
    //printf("number of lines in file = %d\n",pos); return 0;
    //now we will remove <timestamps> and align+position
    j=0;
    for (i=0; i<pos; i++) {
        line=arr[i];
        if (strlen(line)>1){ // if not empty line
            arr[j]=arr[i];
            if (NULL != (ptr=strstr(line," --> "))) { // if timing line
                ptr[17] = '\0'; //strip the text "align:start position:0%"
                l = strlen(line);
                for (m=0; m<=l; m++) {
                    if (line[m]=='.') {
                        line[m]=',';
                    }
                }
            } else { //else subtitle line
                l = strlen(line);
                k = 0;
                erase=0; // boolean: keep or erase text in between <...>
                for (m=0; m<=l; m++){
                    if (line[m]=='<') {erase=1;}
                    else if (line[m]=='>') {erase=0;}
                        else if (!erase) {
                            line[k++] = line[m];
                        }
                }
            }
            //printf("%d:%d:%d: %s\n",i,j, strlen(line), line);
            j++;
        } // else {skip empty line.}
    }
    pos=j;
    //printf("exluding empty lines = %d\nResult:\n",pos); for (i=0; i<pos; i++) {printf("%d:%d: %s\n",i, strlen(line), arr[i]);} return 0;

    // now we will remove duplicate textlines:
    i=0;
    while ((NULL == strstr(arr[i]," --> ")) && (i<pos)){
        i++;
    };// seek to the first timeline
    line = arr[0] = arr[i]; // pointer to first time line
    i++;
    j=1;
    for (; i<pos; i++) {
        ptr=strstr(arr[i]," --> ");
        erase = (strcmp(arr[i],line)==0); // 0==are equals.
        if (ptr == NULL && erase) { // if this textline and duplicate of previous textline
            continue;
        }
        // now to treat timelines and new textlines:
        if (ptr == NULL) { // if isnt timeline
            line = arr[i]; // its new textline
        }
        arr[j] = arr[i];
        j++;
        //printf("%d:%d: %s\n",i, strlen(line), arr[i]);
    }
    pos = j;
    //printf("without duplicate textlines=%d\nResult:\n",pos); for (i=0; i<pos; i++) {printf("%d:%d: %s\n",i, strlen(arr[i]), arr[i]);} return 0;

    // now we will remove duplicate timelines:
    previousline=0; // previous line was 0=textline, 1=timeline
    j=1;
    for (i=1; i<pos; i++) {
        ptr=strstr(arr[i]," --> ");
        if (previousline==1 || ptr==NULL){ // keep this, if previous was textline or this is textline
            arr[j]=arr[i];
            j++;
        } //else { this is second timeline, skip it }
        previousline = (ptr!=NULL)?1:0;
        //printf("%d:%d: %s\n",i, strlen(line), arr[i]);
    }
    pos = j;
    //printf("without duplicate timelines=%d\nResult:\n",pos); for (i=0; i<pos; i++) {printf("%d:%d: %s\n",i, strlen(arr[i]), arr[i]);} return 0;
    printf("Subtitles from file %s loaded.\n", filein);
    
    //create .srt file
    if (argc==3) {
        strcpy(fileout, argv[2]);
    } else {
        k=strlen(filein);
        filein[k-3]='s';filein[k-2]='r';filein[k-1]='t';
        printf("Enter output filename (default: %s) : ",filein);
        fgets (fileout, MAXLINELEN, stdin);
        fileout[strlen(fileout) - 1] = '\0';
    }
    k = strlen(fileout);
    if (k==0) {
        strcpy(fileout, filein); // use default output filename.srt
        k=strlen(fileout);
    }
    if (k<=3 || (strstr(&fileout[k-4],".srt") == NULL)) { // if .srt extension omitted
        strcat(fileout,".srt"); //append missing extension
    }
    fh = fopen(fileout, "w"); // create new file
    if (fh==NULL) {
        printf("File creating error. Sending the result to stdout.\n");
        fh=stdout;
    }

    //find first timeline
    i=0;
    while (!strstr(arr[i]," --> ") && (i<pos)) {
        i++;
    }
    j=1;
    while (i<pos){
        ptr = strstr(arr[i]," --> "); // NULL~textline
        if (ptr) { //if timeline
            fprintf(fh,"%d\n%s\n",j,arr[i]);
            j++;
        } else {
            fprintf(fh,"%s\n\n",arr[i]);
        }
        i++;
        //printf("%d:%d: %s\n",i, stlen(arr[i]), arr[i]);
    }
    if (fh!=stdout) {
        fclose(fh);
    }
    printf("Subtitles exported to %s.\n",fileout);
    free(arr);
    free(buffer);
    return 0;
}

관련 정보