Search code examples
windowsbatch-filecmdyoutube-dl

How to read variable on a IF condition inside a FOR


I am real newbie on batch scripting, the entire code used I've written searching and reading here and on ss64.com.


I'm trying to achieve a solution for a youtube-dl batch script where the video with the best bitrate on the list.txt lines be downloaded, but it cannot be a MKV or use reencode, which takes time and CPU processing. So, I need to get the return extension file to know which command will be specified to run. The one which says to get best video with mp4 extension and m4a audio extension and merge with ffmpeg or the one which says get best video with VP9 codec and best audio with Opus codec, which both are in webm extension and combine into a perfect webm file.

I've already did this for one link case, now I am trying to achieve for a list of links on a txt file.


As it is on youtube-dl FAQ the -a or --batch-file argument, download a list of links on a txt file one link per line, but as I wish to download the best bitrate available I can't use that, because it would resulting getting all the links on which detectable extension. (webm and mp4)

For example, running the .bat using the code below, would result in downloading everything in both extensions.

@echo off
@For /F Delims^=^ EOL^= %%G In ('youtube-dl -f "bestvideo[height<=2160]/best[height<=2160]" --get-filename -o "%%(ext)s" -a LiST.txt') Do (
  if "%%~G" EQU "mp4" (youtube-dl --simulate --console-title -f "bestvideo[height<=2160][ext=mp4]+bestaudio[ext=m4a]/best[height<=2160]" -a LiST.txt)
  if "%%~G" EQU "webm" (youtube-dl --simulate --console-title -f "bestvideo[height<=2160][ext=webm]+bestaudio[ext=webm]/best[height<=2160]" -a LiST.txt)
)

So I had to do this on another way, without using --batch-file / -a


The problem is that the variable looks like it is not read as result of the command called, but like a stringfied command on the IF condition

@echo off
setlocal enableDelayedExpansion
@For /F Delims^=^ EOL^= %%G In (LiST.txt) Do (
  SET ext=youtube-dl -f "bestvideo[height<=2160]/best[height<=2160]" --get-filename -o "%%(ext)s" %%~G &call %%ext%%
  if "!ext!" EQU "mp4" (youtube-dl --simulate --console-title -f "bestvideo[height<=2160][ext=mp4]+bestaudio[ext=m4a]/best[height<=2160]" %%~G)
  if "!ext!" EQU "webm" (youtube-dl --simulate --console-title -f "bestvideo[height<=2160][ext=webm]+bestaudio[ext=webm]/best[height<=2160]" %%~G)
)
pause

I've tried using SET ext with &call %%ext%% and &!ext! in the end of the line, and both appears to be returning as expected, but the IF appears to return the "youtube-dl -f ..." command stringfy, then the condition is never reached. I came to this conclusion after using a

else ( echo !ext! )


PS:

  • the content of the list.txt is youtube links one per line
  • %%G represents each link per line on the txt file
  • I am using --simulate argument just for testing the code

What should I do to read the result of the command on the variable?


Solution

  • At the same folder of the youtube-dl.exe I have the LiST.txt file with youtube links pasted one per line, as the .bat file with the following code.

    • First @For it reads the txt file looking for the youtube links for download and store the link on %%G variable
    • Second For store the result on %%H with the youtube-dl parameters asking for the extension of the best video bitrate available on that link

    Now that we know the best video extension is, we ask to download the best video bitrate filtering by extensions of video and audio that combine. (mp4 & m4a / webm & webm)

    @echo off
    Title [MP4 or WEBM]
    @For /F Delims^=^ EOL^= %%G In (LiST.txt) Do (
      For /F "delims= eol=|" %%H in ('youtube-dl -f "bestvideo[height<=2160]/best[height<=2160]" --get-filename -o "%%(ext)s" %%~G') do (
        if "%%~H" EQU "mp4" (youtube-dl --console-title -f "bestvideo[height<=2160][ext=mp4]+bestaudio[ext=m4a]/best[height<=2160]" %%~G)
        if "%%~H" EQU "webm" (youtube-dl --console-title -f "bestvideo[height<=2160][ext=webm]+bestaudio[ext=webm]/best[height<=2160]" %%~G)
        )
    )
    

    If I didn't do this, it would get the best video and audio without measuring incompatible codecs, which would result most of the times in a mkv file.

    For example a file (webm) with VP9 codec + a bestaudio m4a codec would be merged into a mkv, and would require reencoding the video with ffmpeg as I didn't want that format. A mp4 file merged with an opus audio codec (webm) would give the same result.

    Webm is most of the times best bitrate available for 4K videos. Note that I restricted to 4K [height<=2160] because my computer isn't capable to run 8K.