Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is it possible to output the archive file of a playlist with this syntax: "%(playlist_title)s/downloaded_archive.txt" #9962

Closed
6 of 9 tasks
cococry opened this issue May 19, 2024 · 9 comments
Labels
question Question

Comments

@cococry
Copy link

cococry commented May 19, 2024

DO NOT REMOVE OR SKIP THE ISSUE TEMPLATE

  • I understand that I will be blocked if I intentionally remove or skip any mandatory* field

Checklist

Please make sure the question is worded well enough to be understood

I want the archive file of my playlist to always be in the directory of where my music is. How to do that? Or is it even possible?

Command:

yt-dlp -i --embed-thumbnail --add-metadata --extract-audio --audio-format mp3 --output "%(playlist_title)s/%(playlist_index)s - %(title)s.%(ext)s" --download-archive "%(playlist_title)s/downloaded_archive.txt" <playlist>

Error:

ERROR: [Errno 2] No such file or directory: '%(playlist_title)s/downloaded_archive.txt'

Provide verbose output that clearly demonstrates the problem

  • Run your yt-dlp command with -vU flag added (yt-dlp -vU <your command line>)
  • If using API, add 'verbose': True to YoutubeDL params instead
  • Copy the WHOLE output (starting with [debug] Command-line config) and insert it below

Complete Verbose Output

No response

@cococry cococry added the question Question label May 19, 2024
@DavidPesticcio
Copy link

DavidPesticcio commented May 19, 2024

Have you tried --exec [WHEN:]CMD

I haven't tried exactly as you have it, but with an RSS feed for a podcast it works, so perhaps this will work for you also;

yt-dlp -i --embed-thumbnail --add-metadata --extract-audio --audio-format mp3 --output "%(playlist_title)s/%(playlist_index)s - %(title)s.%(ext)s" --download-archive "downloaded_archive.txt" --exec "after_video:/bin/mv -v downloaded_archive.txt %(playlist_title)s/downloaded_archive.txt" <playlist>

See also for WHEN -

POSTPROCESS_WHEN = ('pre_process', 'after_filter', 'video', 'before_dl', 'post_process', 'after_move', 'after_video', 'playlist')

--exec [WHEN:]CMD               Execute a command, optionally prefixed with
                                when to execute it, separated by a ":".
                                Supported values of "WHEN" are the same as
                                that of --use-postprocessor (default:
                                after_move). Same syntax as the output
                                template can be used to pass any field as
                                arguments to the command. If no fields are
                                passed, %(filepath,_filename|)q is appended
                                to the end of the command. This option can
                                be used multiple times

@bashonly
Copy link
Member

Or is it even possible?

Not without an external script.

Open feature request #953

@bashonly
Copy link
Member

Have you tried --exec [WHEN:]CMD

On repeated runs, this suggestion will prevent yt-dlp from actually checking the archive before downloading, and mv would either clobber the existing archive file or fail

@DavidPesticcio
Copy link

DavidPesticcio commented May 19, 2024

This works (updated from %()s to %()q as per comments below from @bashonly)

Repeated runs will cause repeated entries for each ID in downloaded_archive.txt

Solved with sort -u downloaded_archive.txt -o downloaded_archive.txt

The rest is on you @cococry... 😃

yt-dlp -i --embed-thumbnail --add-metadata --extract-audio --audio-format mp3 --output "%(playlist_title)s/%(playlist_index)s - %(title)s.%(ext)s" --download-archive "downloaded_archive.txt" --exec "after_video:/bin/cat downloaded_archive.txt | tee -a %(playlist_title)q/downloaded_archive.txt; rm downloaded_archive.txt" https://youtube.com/playlist?list=PL0vfts4VzfNjQOM9VClyL5R0LeuTxlAR3

@bashonly
Copy link
Member

bashonly commented May 19, 2024

A word of caution: using %()s in an --exec arg is NEVER safe -- if the value contains an ' it can escape your quoting and execute arbitrary shell commands

@DavidPesticcio
Copy link

A word of caution: using %()s in an --exec arg is NEVER safe -- if the value contains an ' it can escape your quoting and execute arbitrary shell commands

Sure, but that's something that yt-dlp should manage. After all, it's yt-dlp that's expanding the values of any %()s used.

@bashonly
Copy link
Member

Sure, but that's something that yt-dlp should manage. After all, it's yt-dlp that's expanding the values of any %()s used.

No. You are responsible for how you use --exec. And %()q should always be used, NOT %()s.

@DavidPesticcio
Copy link

Sure, but that's something that yt-dlp should manage. After all, it's yt-dlp that's expanding the values of any %()s used.

No. You are responsible for how you use --exec. And %()q should always be used, NOT %()s.

Ah, so yt-dlp does mitigate those sort of issues by escaping/quoting problematic values that it expands.

Is there a documented example and explanation of why %()q should be favoured over %()s when using --exec? - I couldn't find anything, other than a passing mention of it in the README.md. 🫤

@bashonly
Copy link
Member

https://github.com/yt-dlp/yt-dlp#output-template

  1. More Conversions:

q = a string quoted for the terminal (flag # to split a list into different arguments)

Again, though, you are responsible for how you use --exec. It is basically just running commands with your shell. Your shell's documentation doesn't come with a warning telling you not to rm -rf /

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Question
Projects
None yet
Development

No branches or pull requests

3 participants