2017-03-15 36 views
13

我需要下載一個mp3文件,但我只需要歌曲的前20秒(或者如果歌曲少於20秒,整首歌曲)。
我這是怎麼下載整首歌曲:ios - 從mp3文件下載只有幾秒鐘

func downloadSong(audioUrl: URL) { 

    let documentsDirectoryURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first! 
    let destinationUrl = documentsDirectoryURL.appendingPathComponent(audioUrl.lastPathComponent) 

    URLSession.shared.downloadTask(with: audioUrl, completionHandler: { (location, response, error) -> Void in 
     guard let location = location, error == nil else { return } 
     do { 

      try FileManager.default.moveItem(at: location, to: destinationUrl) 
      // song available in destinationUrl 

     } catch let error as NSError { 

     } 
    }).resume() 
} 

有沒有辦法阻止20秒後下載? 我知道我可以下載整首歌曲然後剪切它,但我想要更有效率,尤其是如果歌曲很長。

+1

首先,下載20秒不會確保您可以播放20秒。沒有辦法100%確定你有20秒的音頻,你可能只想使用一個音頻流並且流文件並在20秒後停止流。或者在服務器上提供20秒mp3文件。 – rckoenes

+0

@rckoenes你的權利我的意思是最大20秒,它可能更少 – Eyal

+1

不可能我的兄弟,因爲首先確定歌曲的信息,並不知道如果20秒下載和MP3播放罰款可能有可能丟失任何幀在20秒比不播放mp3 –

回答

7

MP3文件被劃分成小塊 - 幀。每幀有 恆定時間長度0.026秒。但是一幀的大小(以字節計) 根據比特率而變化。例如。對於128kbps,它是(通常)417 字節和192kbps 626字節。每幀的前4個字節爲 幀頭,其餘爲音頻數據。

引用自here

並且每幀都是可播放的。因此,對於20秒的數據,您需要大約770 frames(20/0.026)。 因此先下載770幀,然後取消下載任務。然後播放你下載的幀。

按尺寸首先下載313.5 KB(計算結果爲:(417 Bytes*770)/1024)128kbps文件的數據。你會得到20秒的數據。

+0

我想你也應該回答如何下載第一個'313.5 KB'。 –

+0

這是我也會給出的答案。 Upvoted。 –

+0

還沒有機會檢查這個,但這是迄今爲止最詳細和實際的答案,我會稍後更新結果。謝謝 – Eyal

2

您必須將音頻文件剪切爲20秒,然後才能下載它。

+0

是的,明確的路要走。而且:所有的ID標籤都應該被剝離出來。這是迄今爲止使用服務器端批處理腳本執行此類任務的最快捷方式。所有其他解決方案需要讀取mp3文件,直到所有聲音幀的長度達到20秒。 – deblocker

2

我在我的一個應用程序中也遇到過這樣的挑戰。之後,我搜尋了很多,我終於認定這是不可能的。由於下載mp3文件有自己的內部algorithm,它根據幀進行工作。 因此,我們無法預測我們下載的音頻有多少秒鐘或幾分鐘。

此外,您可以參考此鏈接。

Download last 30 seconds of an mp3

1

從我看來,這是絕對有可能只有幾個假設:

  • 服務器應支持Content-Range
  • 你需要一些知識(或好圖書館)內部的mp3結構

的主意:

通過請求此範圍內的計數從服務器下載500 kb。然後,你有兩個選擇:

  1. 快速而骯髒 - 交叉手指和直接提供這一數據的球員,看看:)
  2. 供應接收到的數據爲MP3感知庫發生了什麼(或者手動解析頭) 。元數據中的補丁文件長度,然後嘗試播放它肯定是