2014-02-08 45 views
1

我想要顯示來自我的Track-URL的soundcloud曲目的插圖圖像。在facebook api中是否存在soundcloud圖片網址方案?

我知道當我從URL中提取軌道密鑰/ id時,我可以通過它的API請求圖片的URL,然後將檢索到的URL注入圖片標籤。

我想知道的是,如果它可能使用某種URL模式,使聲音雲向前瀏覽器正確的藝術品URL,如可能與Facebook配置文件圖像。

例如:

馬克Zuckerbergs當前資料圖片的URL是http://profile.ak.fbcdn.net/hprofile-ak-prn2/t5/202896_4_1782288297_q.jpg

那是一些神祕的東西,因爲它在一個CDN託管。 Soundcloud的作品網址也非常神祕。

現在,當我知道馬克的Facebook ID /鍵(「扎克」),我可以簡單地訪問像這樣他的個人資料圖片:

http://graph.facebook.com/zuck/picture

該URL被自動轉發到個人資料圖片網址facebook API。

使用此URL架構,您不僅可以抽象出額外API請求的原因,還可以安全處理他們的時間。

對soundcloud track藝術品是否有這樣的功能?

回答

0

我寫了一個明確的應用程序,可重定向至可用最大圖像上的CDN給出artwork_url

https://gist.github.com/gaearon/717ed6d6c7771f95d50d

它使用自己的命名方案,並列舉大小逐一直到一些圖像返回狀態200

來源:

'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;