Konvertieren Sie automatisch generierte Untertitel mit youtube-dl in das SRT-Format

Konvertieren Sie automatisch generierte Untertitel mit youtube-dl in das SRT-Format

Ich möchte generierte Untertitel von YouTube herunterladen und sie mit einem Befehl in das SRT-Format konvertieren. youtube-dl --write-auto-sub --sub-lang en --convert-subs=srt --skip-download <URL>Es wird nur eine VTT-Datei ausgegeben und nicht in das SRT-Format konvertiert.

Aber wenn --skip-downloades entfernt wird, wird das Video und die VTT-Datei heruntergeladen und anschließend VTT in SRT konvertiert.

Gibt es eine Möglichkeit, nur die VTT-Datei herunterzuladen und sie dann in SRT zu konvertieren, ohne das Video herunterzuladen?

Antwort1

Der Grund dafür liegt vielleicht darin, dass ffmpeg, das in diesem Prozess im Hintergrund verwendet wird, Recodierungsanforderungen wie „ffmpeg.exe -i path.vtt path.vtt.srt“ nicht direkt verarbeitet. Es benötigt einen Stream zur Datei und dafür eine Videodatei.

Zumindest funktioniert eine solche Anfrage bei mir nicht und meldet das Ausbleiben eines Streams, obwohl es im Internet ähnliche Beispiele gibt.

Antwort2

Ich habe ein sehr einfaches Befehlszeilentool zum Konvertieren von VTT in SRT erstellt. Es funktioniert über eine sehr einfache Textverarbeitung (keine lexikalische Analyse oder Verwendung von Token) und nur für die automatisch transkribierten Untertitel von YouTube, für einen Text wie diesen:

WEBVTT Art: Untertitel Sprache: en

00:00:01.740 --> 00:00:05.030 align:start position:0%
nichts<00:00:02.700> ist<00:00:03.179> unmöglich...

Sie können es hier als ZIP-Datei herunterladen:http://pececko.szm.com/@ VTT to SRT. Ich habe nicht vor, es zu aktualisieren, also betrachten Sie diesen Code bitte als öffentliches Eigentum. Ich hoffe, das kann für jemanden nützlich sein.

// 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;
}

verwandte Informationen