Eyal
Eyal

Reputation: 10828

ios - download only few seconds from mp3 file

i need to download a mp3 file, but i only need the first 20 seconds of the song (or the entire song if the song is less than 20 sec).
this is how i download the entire song:

    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()
}

is there a way to stop the download after 20 seconds? i know i can download the entire song and then cut it, but i want to be more efficient, especially if the song is very long.

Upvotes: 13

Views: 1335

Answers (4)

sage444
sage444

Reputation: 5684

From my opinion this is definitely possible with only few assumptions:

  • Server should support Content-Range header
  • you need some knowledge (or good library) in internal mp3 structure

The idea:

Download 500 kb from server by requesting this count in range. Then you have two option:

  1. fast-and-dirty - cross fingers and supply this data directly to player and see what happens:)
  2. Supply received data to mp3-aware library (or manually parse header). Patch file length inside metadata and then try to play it this time for sure

Upvotes: 1

Partho Biswas
Partho Biswas

Reputation: 2330

MP3 file is divided into a small blocks - frames. Each frame has constant time length 0.026 sec. But size of one frame (in Bytes) varies according to bitrate. Eg. for 128kbps it is (normally) 417 Bytes and for 192kbps 626 Bytes. The first 4 Bytes of each frame is frame header and the rest is audio data.

Quoted from here.

And each frame is playable. So for 20 seconds of data, you need approximately 770 frames(20/0.026). So download first 770 frames then cancel the download task. Then play your downloaded frames.

Or by size, download first 313.5 KB (Calculation is: (417 Bytes*770)/1024) of data for 128kbps file. And you will get your 20 seconds of data.

Upvotes: 7

Arpit Jain
Arpit Jain

Reputation: 1690

I have also faced such challenge in one of my application. After, searching a lot I finally concluded it is not possible. As downloading an mp3 file has its own internal algorithm which works according to frames. So, we cannot predict anything regarding how much seconds or minutes of audio we have downloaded.

Further, you can refer this link.

Download last 30 seconds of an mp3

Upvotes: 2

Jamie Lipper
Jamie Lipper

Reputation: 21

You would have to cut the audio file to 20 seconds, then you could download it.

Upvotes: 2

Related Questions