Open emphoeller opened 4 years ago
Was able to replicate this on my machine. It looks like BandcampIE (the extractor for individual tracks on Bandcamp) doesn't include any code for retrieving the description, so this is a missing feature rather than a bug.
Currently, BandcampIE pulls all its metadata out of a JSON object in the page: the trackinfo
property of the TralbumData
variable. The description of the song can be found in the current
property of the TralbumData
variable. Actually, the description is made of two parts, current.about
and current.lyrics
. Given that Bandcamp's website displays these as though they were one continuous description, it seems like it'd be easiest if youtube-dl combined them as well.
Here's some untested code for BandcampIE's _real_extract()
method that would pull those two fields out of TralbumData.current
, then combine them into one variable:
current = self._parse_json(
self._search_regex(
r'current\s*:\s*\[\s*({.+?})\s*\]\s*,\s*?\n',
webpage, 'current', default='{}'), title)
if current:
about = str_or_none(current.get('about'))
lyrics = str_or_none(current.get('lyrics'))
description = "\n\n".join(filter(None, (about, lyrics)))
If only one of the two values is set, then description
will just be set to that value. If they're both set, description
will be set to a concatenation of both, with two line breaks added between them.
This code is based on the existing track_info
code in BandcampIE, and can be dropped in immediately after that code on line 117. You'd also need to add the description to the function's return value on line 204.
You could also add the same functionality to BandcampAlbumIE with similar code. However, albums don't have lyrics, so you would only need the about
field.
Here’s what I came up with, based on your code:
tralbumdata_current = self._parse_json(
self._search_regex(
r'TralbumData\s*=\s*\{.*?current\s*:\s*(\{.*?\})',
webpage, 'track description', default='{}'), title)
description = None
if tralbumdata_current:
description = '\r\n\r\n'.join(filter(None, (
str_or_none(tralbumdata_current.get('about')),
str_or_none(tralbumdata_current.get('lyrics')))))
My modifications explained:
tralbumdata_current
instead of current
as it is a bit more informative.TralbumData = {
so not just any current
in the webpage is matched.\[
\]
since current
is not an array..+?
to .*?
inside the capturing group in order to match {}
.'track description'
) to _search_regex
– it appears in error messages, and “current” is not very transparent.about
and lyrics
.I have also added 'description': description,
to the return dictionary. However, right now I can’t figure out how to actually execute my modified code, as whenever I call python3 ./youtube-dl/youtube_dl/ --write-description 'https://virt.bandcamp.com/track/hyper-camelot-guest-director-boss-battle'
, the program executes unchangedly, even when I print something, raise an exception, or produce a syntax error. How do I run my code properly?
Also a side question: What happens when about
or lyrics
contains }
? Wouldn’t that have the regex cut off there, which would lead to an incomplete JSON string with an unterminated string literal being parsed, resulting in an error?
Checklist
Verbose log
Description
Attempting to download a track description from Bandcamp using
--write-description
results inWARNING: There's no description to write.
and no file being written, even though a description is present. As you can see here, the track used above does have a description. Is this maybe not supported at all for Bandcamp yet, making this more of a feature request? (In that case, the current warning is giving the user the wrong idea.)