10

For example:

http://soundcloud.com/mhiqu3/sets/heretik/

How to get the thumbnail url: http://i1.sndcdn.com/artworks-000004897289-5r6ws9-large.jpg?1767646

with the api (or without) ?

bux
  • 7,087
  • 11
  • 45
  • 86

5 Answers5

26

I know this is quite old, but I stumbled in this question looking for something else and I'd like to give my two cents.

These are all possible sizes (source API Reference):

        * t500x500:     500×500
        * crop:         400×400
        * t300x300:     300×300
        * large:        100×100 (default)
        * t67x67:       67×67    (only on artworks)
        * badge:        47×47
        * small:        32×32
        * tiny:         20×20    (on artworks)
        * tiny:         18×18    (on avatars)
        * mini:         16×16
        * original:     (originally uploaded image)
Andrea Sciamanna
  • 1,404
  • 1
  • 15
  • 30
9

also, if you replace the "-large" in the url string with "-t300x300" or "-t500x500" you will have access to the larger formats.

Matas Petrikas
  • 216
  • 1
  • 5
7

You can use the /tracks endpoint, and read the artwork_url property from the returned JSON. More details: http://developers.soundcloud.com/docs/api/tracks

sborsje
  • 601
  • 5
  • 7
  • 1
    Is there no way but to make an API request every time? Facebook has this graph url that directly just returns a picture... – Aditya M P Jul 02 '14 at 13:50
  • As by today Soundcloud tracks html page includes a `og:image` meta tag: ` ` So now it should be possible to retrieve the artwork without the API using plain PHP or Javascript, even it could be tricky as the header of this page gives an "301 Moved Permanently" HTTP code. – geraldo May 06 '16 at 21:25
4

what you want to do is use Soundclouds API like so:

SC.get(PATH, function (track, err){
  IMG_URL = track.artwork;
});

you can see an example here: http://runnable.com/UuiMCfATvMMkAAAS/get-a-tracks-artwork-on-soundcloud-in-javascript#

the PATH to the track can be obtained in different ways
1. if you know the image id you can grab it like so
var PATH = "/tracks" + id;
2. if you know the name and user of the track
var PATH = "/users/dj-faze/tracks/phase-shift-360-019-degrees"
3. you can also get the id with other soundcloud API's

NOTE: Ensure the track's image you are trying to get is public. If it is private your going to have to log in with soundcloud authorization API.

AnandKumar Patel
  • 980
  • 9
  • 18
3

I tried to use this answer but unfortunately SoundCloud doesn't seem to guarantee that t500x500, original or other sizes will exist.

So I resorted to writing an express app that redirects to largest available image on their CDN, given artwork_url.

FixSoundCloudArtworkUrl.js

It uses their naming scheme and enumerates sizes one by one until some image returns status 200.

Source:

'use strict';

var express = require('express'),
    app = express();

require('./config/development')(app, express);
require('./config/production')(app, express);

var redis = require('redis'),
    request = require('request'),
    Promise = require('bluebird');

Promise.promisifyAll(redis.RedisClient.prototype);

var redisSettings = app.set('redis'),
    redisClient = redis.createClient(redisSettings.port, redisSettings.host, redisSettings.options);

app.configure(function () {
  app.use(express.bodyParser());
  app.use(app.router);
});

function sendError(res, status, error) {
  if (!(error instanceof Error)) {
    error = new Error(JSON.stringify(error));
  }

  return res
    .status(status || 500)
    .end(error && error.message || 'Internal Server Error');
}

function generateCacheHeaders() {
  var maxAge = 3600 * 24 * 365;

  return {
    'Cache-Control': 'public,max-age=' + maxAge,
    'Expires': new Date(Date.now() + (maxAge * 1000)).toUTCString()
  };
}

function getCacheKey(url) {
  return 'soundcloud-thumbnail-proxy:' + url;
}

app.get('/*', function (req, res) {
  var originalUrl = req.params[0],
      cacheKey = getCacheKey(originalUrl),
      urls;

  // https://developers.soundcloud.com/docs/api/reference#artwork_url
  // This is a ridiculous naming scheme, by the way.

  urls = [
    originalUrl,
    originalUrl.replace('-large', '-t500x500'),
    originalUrl.replace('-large', '-crop'), // 400x400
    originalUrl.replace('-large', '-t300x300'),
    originalUrl.replace('-large', '-large') // 100x100
  ];

  return redisClient.getAsync(cacheKey).then(function (cachedUrl) {
    if (cachedUrl) {
      return cachedUrl;
    }

    return Promise.reduce(urls, function (resolvedUrl, url) {
      if (resolvedUrl) {
        return resolvedUrl;
      }

      return new Promise(function (resolve) {
        request.head(url, function (err, response) {
          if (!err && response.statusCode === 200) {
            resolve(url);
          } else {
            resolve(null);
          }
        });
      });
    }, null);
  }).then(function (url) {
    if (!url) {
      throw new Error('File not found');
    }

    var headers = generateCacheHeaders();
    for (var key in headers) {
      if (headers.hasOwnProperty(key)) {
        res.setHeader(key, headers[key]);
      }
    }

    res.redirect(url);
    redisClient.set(cacheKey, url);
    redisClient.expire(cacheKey, 60 * 60 * 24 * 30);

  }).catch(function (err) {
    sendError(res, 404, err);
  });

});

app.get('/crossdomain.xml', function (req, res) {
  req.setEncoding('utf8');
  res.writeHead(200, { 'Content-Type': 'text/xml' });
  res.end('<?xml version="1.0" ?><cross-domain-policy><allow-access-from domain="*" /></cross-domain-policy>');
});

redisClient.on('ready', function () {
  app.listen(app.set('port'));
});

redisClient.on('error', function () {
  throw new Error('Could not connect to Redis');
});

module.exports = app;
Edgar
  • 6,022
  • 8
  • 33
  • 66
Dan Abramov
  • 264,556
  • 84
  • 409
  • 511