2014-09-02 68 views
2

我試圖從應用程序中使用ruby sdk(soundcloud 0.2.0 gem)從Soundcloud下載曲目。我已經在soundcloud上註冊了該應用程序,並且client_secret是正確的。我知道這一點,因爲我可以使用應用程序查看我的個人資料信息和曲目。 現在,當我嘗試使用下面的代碼使用Ruby SDK從Soundcloud下載曲目

@track = current_user.soundcloud_client.get(params[:track_uri]) 
data = current_user.soundcloud_client.get(@track.download_url) 
File.open("something.mp3","wb"){|f|f.write(data)} 

下載的軌道,當我打開文件時,它沒有任何關係了。我試過很多方法,包括下面的一個,

data = current_user.soundcloud_client.get(@track.download_url) 
file = File.read(data) 

而這一次給我一個錯誤

can't convert nil into String 

上是

app/controllers/store_controller.rb:13:in `read' 

線13是File.read功能。

我有雙重檢查,我試圖下載的曲目是公開的和可下載的。 我試圖通過從控制檯複製它並使用郵遞員發送請求來測試正在顯式使用的download_url,並且它工作正常。我不確定爲什麼當其他的東西工作的很好時,它不能與應用程序一起工作。

我想要做的是成功地能夠下載或至少獲得我可以存儲在某個地方的數據。

版本的詳細信息: -
紅寶石1.9.3p194(2012-04-20修訂35410)x86_64的Linux的]
的Rails 3.2.18
的SoundCloud 0.2.0

+0

顯然'nil'是來自'soundcloud_client.get(...)'的有效響應(或者至少是一個可能的響應),所以你應該測試和處理這種可能性。 – 2014-09-02 12:38:19

回答

6

有幾個假設你在做這件事之前必須明白。

  • 並非SoundClound上的所有曲目都可以下載!只有被標記爲的曲目可以下載 - 您的代碼必須考慮該選項!
  • 在下載download_url之前,您的曲目URL必須「已解決」,獲得download_url後,您必須使用client_id獲取最終下載URL。
  • 音軌可能很大,而且它們需要時間!您絕不應該在您的控制器或模型中直接從您的Rails應用程序執行此類任務。如果任務運行時間較長,則始終使用一些後臺處理程序或某種其他類型的後臺處理「事物」 - 例如,Sidekiq

命令行客戶端的例子

這是例如工作的客戶,你可以用它來從SoundClound下載曲目。它使用官方的Official SoundCloud API Wrapper for Ruby,假設你使用的是Ruby 1.9.x,它不以任何方式依賴於Rails。

# We use Bundler to manage our dependencies 
require 'bundler/setup' 

# We store SC_CLIENT_ID and SC_CLIENT_SECRET in .env 
# and dotenv gem loads that for us 
require 'dotenv'; Dotenv.load 

require 'soundcloud' 
require 'open-uri' 

# Ruby 1.9.x has a problem with following redirects so we use this 
# "monkey-patch" gem to fix that. Not needed in Ruby >= 2.x 
require 'open_uri_redirections' 

# First there is the authentication part. 
client = SoundCloud.new(
    client_id: ENV.fetch("SC_CLIENT_ID"), 
    client_secret: ENV.fetch("SC_CLIENT_SECRET") 
) 

# Track URL, publicly visible... 
track_url = "http://soundcloud.com/forss/flickermood" 

# We call SoundCloud API to resolve track url 
track = client.get('/resolve', url: track_url) 

# If track is not downloadable, abort the process 
unless track["downloadable"] 
    puts "You can't download this track!" 
    exit 1 
end 

# We take track id, and we use that to name our local file 
track_id = track.id 
track_filename = "%s.aif" % track_id.to_s 
download_url = "%s?client_id=%s" % [track.download_url, ENV.fetch("SC_CLIENT_ID")] 

File.open(track_filename, "wb") do |saved_file| 
    open(download_url, allow_redirections: :all) do |read_file| 
    saved_file.write(read_file.read) 
    end 
end 

puts "Your track was saved to: #{track_filename}" 

另請注意,文件位於AIFF (Audio Interchange File Format)。要將它們轉換爲mp3,您可以使用ffmpeg來做這種事。

ffmpeg -i 293.aif final-293.mp3 
+1

例如,有ffmpeg的Ruby綁定:https://github.com/tja/ruby-ffmpeg。 :) – 2014-09-02 12:50:54

+0

哦是的,+1建議使用後臺處理。 – 2014-09-02 12:51:33

+0

我的確如你所說,但現在我得到這個, 沒有這樣的文件或目錄 - https://api.soundcloud.com/tracks/158307369/download?client_id=xxxxxx 使用相同的片段你提出了答案。 – user3173575 2014-09-02 17:06:09