Próbuję zmniejszyć rozdzielczość wideo na poziomie 500x500. Nie chcę go zmienić dokładnie 500x500, ponieważ stanowiłoby jakość wideo. Więc co próbuję zrobić, to zmniejszyć uchwałę o 75% w pętli, a pętla zatrzyma się tylko wtedy, gdy wideo jest poniżej 500x500. W teorii, która nie byłaby trudna, ale nie mogę tego wymyślać.

var vidwidth = 501; //Create variable and put it to 501
var vidheight = 501; //so that it won't go through the If Statement
fs.copyFile(filepath2, './media/media.mp4', (err: any) => { //Copy given file to directory
    console.log('filepath2 was copied to media.mp4'); //Log confirmation (Not appearing for some reason, but file is copied)
})
while (true) {
    getDimensions('./media/media.mp4').then(function (dimensions: any) { //Get dimensions of copied video
        var vidwidth = parseInt(dimensions.width)   //Parse to Int
        var vidheight = parseInt(dimensions.height) //and put in variables
    })
    ffmpeg('./media/media.mp4')                 //Call ffmpeg function with copied video path
        .output('./media/media.mp4')            //Set output to the same file so we can loop it
        .size('75%')                            //Reduce resolution by 75%
        .on('end', function() {                 //Log confirmation on end
            console.log('Finished processing'); //(Not appearing)
        })                                      //
        .run();                                 //Run function
    if (vidwidth < 500 && vidheight < 500) {    //Check if both the width and height is under 500px
        break;                                  //If true, break the loop and continue
    }
}

Jest to bieżący kod, którego używam z komentarzami. Zasadniczo, co się dzieje, jest utknął w pętli, ponieważ wymiary wideo nie zmieni się. Testowany z linią console.log(). Myślę, że jeśli mogę naprawić problem FFMPEG, wszystko zostanie naprawione. Byłbym wdzięczny za wszelką pomoc :)

PS: Wszystko jest wykonane w maszynach, a następnie zbuduj do JS za pomocą npx tsc

2
WoJo 24 lipiec 2020, 16:29

1 odpowiedź

Najlepsza odpowiedź

Problem polega na tym, że pętla zapobiega zwrotowi połączeń zwrotnych, ponieważ JavaScript działa na jednym wątku (przeczytaj więcej o tym w tym inne pytanie: Callback funkcji asynchronicznej nigdy nie nazywa się). Jednym z tych zwrotów, które nie zostaną wywołane, jest zwrotne then, gdzie zmieniają się zmienne vidwidth i {x2}} i {x2}} i {x2}}, więc stan sprawdza, czy są mniej niż 500 i ostatecznie przerwa pętla nigdy nie jest true, a pętla utrzymuje się na zawsze. Nie jest to właściwy sposób radzenia sobie z funkcjami asynchronicznymi (czytaj więcej o tym w tym drugim więc pytanie: Jak zwrócić odpowiedź asynchroniczne połączenie?).

Nawiasem mówiąc Na nich i rozpocznij zadanie ffmpeg (ffmpeg będzie obsługiwać utworzenie powstałego pliku bez zmiany pliku wejściowego, więc nie ma potrzeby copyFile). Jak więc:

getDimensions(filepath2).then((dimensions: any) => {                            // get the dimension of the input file
  let sizeStr = dimensions.width < dimensions.height ? "?x500" : "500x?";       // if width is smaller than height, reduce the height to 500 and calculate width based on that, same goes for the other way around
  
  ffmpeg(filepath2)                                                             // the input is the original video, don't worry 'ffmpeg' won't alter the input file
    .output('./media/media.mp4')                                                // the output file path
    .size(sizeStr)                                                              // use the 'sizeStr' string calculated previously (read more about it here: https://github.com/fluent-ffmpeg/node-fluent-ffmpeg#video-frame-size-options) 
    .on('end', () => console.log('Finished processing'))
    .run();       
});

Tak proste jak to!

2
ibrahim mahrir 24 lipiec 2020, 14:43