youtube-dl: Bandcamp is broken

Checklist

  • I’m reporting a broken site support
  • I’ve verified that I’m running youtube-dl version 2020.09.20
  • I’ve checked that all provided URLs are alive and playable in a browser
  • I’ve checked that all URLs and arguments with special characters are properly quoted or escaped
  • I’ve searched the bugtracker for similar issues including closed ones

Verbose log

youtube-dl -v https://proper-t.bandcamp.com/album/the-project-ivy-part-2-beauty-sleep
[debug] System config: []
[debug] User config: []
[debug] Custom config: []
[debug] Command-line args: ['-v', 'https://proper-t.bandcamp.com/album/the-project-ivy-part-2-beauty-sleep']
[debug] Encodings: locale UTF-8, fs utf-8, out utf-8, pref UTF-8
[debug] youtube-dl version 2020.09.20
[debug] Python version 3.8.5 (CPython) - macOS-10.15.6-x86_64-i386-64bit
[debug] exe versions: ffmpeg 4.3.1, ffprobe 4.3.1, rtmpdump 2.4
[debug] Proxy map: {}
[Bandcamp:album] the-project-ivy-part-2-beauty-sleep: Downloading webpage
WARNING: unable to extract title; please report this issue on https://yt-dl.org/bug . Make sure you are using the latest version; see  https://yt-dl.org/update  on how to update. Be sure to call youtube-dl with the --verbose flag and include its complete output.
[download] Downloading playlist: the-project-ivy-part-2-beauty-sleep
[Bandcamp:album] playlist the-project-ivy-part-2-beauty-sleep: Collected 7 video ids (downloading 7 of them)
[download] Downloading video 1 of 7
[Bandcamp] beauty-sleep: Downloading webpage
ERROR: No video formats found; please report this issue on https://yt-dl.org/bug . Make sure you are using the latest version; see  https://yt-dl.org/update  on how to update. Be sure to call youtube-dl with the --verbose flag and include its complete output.
Traceback (most recent call last):
  File "/usr/local/lib/python3.8/site-packages/youtube_dl/YoutubeDL.py", line 797, in extract_info
    ie_result = ie.extract(url)
  File "/usr/local/lib/python3.8/site-packages/youtube_dl/extractor/common.py", line 532, in extract
    ie_result = self._real_extract(url)
  File "/usr/local/lib/python3.8/site-packages/youtube_dl/extractor/bandcamp.py", line 196, in _real_extract
    self._sort_formats(formats)
  File "/usr/local/lib/python3.8/site-packages/youtube_dl/extractor/common.py", line 1359, in _sort_formats
    raise ExtractorError('No video formats found')
youtube_dl.utils.ExtractorError: No video formats found; please report this issue on https://yt-dl.org/bug . Make sure you are using the latest version; see  https://yt-dl.org/update  on how to update. Be sure to call youtube-dl with the --verbose flag and include its complete output.

Description

Bandcamp links return error today

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 43
  • Comments: 15

Commits related to this issue

Most upvoted comments

Will be fixed in the next version.

I noticed the data structures in the Bandcamp HTML file have changed. I have a custom Bandcamp HTML parser (for extracting metadata to use for IDv3 tags) that stopped working at the same time that youtube-dl stopped working. It must have broke for the same reason.

Previously, album metadata was saved to a JS variable in a HTML <script> tag like this:

var TralbumData = { 
    …
};

Now, the same data has been moved inside the data-tralbum attribute of a script tag:

<script type="text/javascript"  …  data-tralbum="{ … }"  …  ></script>

The script tag contains several data- attributes, but the data-tralbum attribute is the one that contains the file URL links – it appears to me to contain the same data that was previously available in the TralbumData variable.

I don’t have time to offer any help to update youtube-dl, but hopefully the above hints help someone who can help.

@mkrupczak3 not really related to this issue, but here’s a partial answer to your question: https://github.blog/2020-11-16-standing-up-for-developers-youtube-dl-is-back/

Basic working example in Ruby, which I just wrote to use until this is fixed here. Feel free to use for reference.


require 'curb'
require 'nokogiri'
require 'ostruct'
require 'pry'
require 'securerandom'
require 'json'
require 'id3lib'
require 'time'

def getnoko(curl_res)
  Nokogiri::HTML.parse(curl_res.body_str)
end

def gethref(str, domain)
  str.match(/^\//) ? "https://#{domain}#{str}" : str
end

url = ARGV[0].gsub("http://","https://")

puts url.inspect

page = getnoko(Curl.get(url))

mp3script = page.css('script').select{|x|x.to_html.include?('bcbits.com/stream')}

tralbum = mp3script[0].attr('data-tralbum')

manifest = JSON.parse(tralbum)

album = manifest['current']['title']
time = Time.parse(manifest['current']['release_date'])

tracks = manifest['trackinfo']

list = tracks.each_with_index do |x, i|
  title = x['title']
  url = x['file']['mp3-128']
  trackNum = i + 1
  filepath = trackNum.to_s.rjust(2, "0") + " - " + title.gsub(/[^,?a-zA-Z0-9 _'"-]/, '') + ".mp3"

  puts "Downloading #{title} to #{filepath} from #{url} ..."

  Curl::Easy.download(url, filepath)
  
  # Tag
  tag = ID3Lib::Tag.new(filepath)
  tag.title = title
  tag.artist = manifest['artist']
  tag.album = album
  tag.track = "#{trackNum}/#{tracks.count}"
  tag.year = time.year
  tag.update!
end

Having the same issue, hoping there’s a fix soon!

It’s more than the metadata, it’s looking for file formats and download URLs. That data has also been moved to a different data structure.

I tried a little bit to parse out the URLs and was able to identify them (search the source for mp3-128) but it needs more analysis to match files with their metadata, and possibly a more general solution for multiple file types.

I confirm it work fine now!

Def will be using the contact option at the bottom of the letter.

Uh, I hate to ask this, but could this latest update to yt-dl for bandcamp de-obfuscation be in anyway perceived as an anti-circumvention measure?

Might be better to be proactive than reactive to this in light of recent events

❤️

Glad to see Microsoft/GitHub standing up for the little guy.

The DMCA is a disaster piece of legislation, and the anti-circumvention clause is so broad I’m surprised it hasn’t been rendered worthless by case law