Open yoondj98 opened 1 month ago
Are you putting the url that you get from this directly into AVPlayer?
And what do you put in contentStart
and contentEnd
in the example where it doesn't work?
I use Your library to make audio URL(like https://rr6---~~~) from Youtube URL(ex) https://youtu.be/pVrcTpriJto?si=TNssoKuae3dvnIkn).
Then I get some part of audio with this code
components.queryItems?.append(URLQueryItem(name: "range", value: "\(contentStart)-\(contentEnd)"))
let fileName = generateFileName(from: audioURL)
let destinationURL = documentsDirectory.appendingPathComponent("new222322323")
print("destinationURL.path", destinationURL.path)
// μ΄λ―Έ νμΌμ΄ μ‘΄μ¬νλμ§ νμΈ
if !fileManager.fileExists(atPath: destinationURL.path) {
do {
let (totalBytes, _) = try await fetchFileMetadata(from: audioURL)
print("totalBytes", totalBytes)
let bytesPerSecond = Double(totalBytes) / 21600
let startByte = Int(bytesPerSecond * 0) // start byte
let endByte = Int(bytesPerSecond * 1000) // end byte
// URLRequest μμ±
var request = URLRequest(url: audioURL) // ex) audioURL= https://rr6--~~
request.addValue("bytes=\(startByte)-\(endByte)", forHTTPHeaderField: "Range")
let (data, response) = try await URLSession.shared.data(for: request)
// λ€μ΄λ‘λν λ°μ΄ν°λ₯Ό λ‘컬μ μ μ₯
try data.write(to: destinationURL) // destinationURL is my device file URL where downloaded file exists
} catch {
return .failure(.copyFailed(error))
}
}
-> I put in the byte of the initial time and finish time
// HTTP HEAD μμ²μΌλ‘ λ©νλ°μ΄ν°λ₯Ό κ°μ Έμ€λ ν¨μ
private func fetchFileMetadata(from url: URL) async throws -> (totalBytes: Int, totalDuration: Double?) {
var request = URLRequest(url: url)
request.httpMethod = "HEAD" // HEAD μμ²μΌλ‘ νμΌ λ©νλ°μ΄ν°λ§ κ°μ Έμ΄
let (_, response) = try await URLSession.shared.data(for: request)
if let httpResponse = response as? HTTPURLResponse,
let contentLength = httpResponse.value(forHTTPHeaderField: "Content-Length"),
let totalBytes = Int(contentLength) {
let totalDuration: Double? = httpResponse.value(forHTTPHeaderField: "X-Content-Duration").flatMap(Double.init)
return (totalBytes, totalDuration)
} else {
throw URLError(.badServerResponse)
}
}
When I put let startByte = Int(bytesPerSecond 0), It works. But, If I put let startByte = Int(bytesPerSecond 10), It doesn't works.
So an audio file is, very simply put, set up like this: First bytes in the file is metadata that defines the codec etc for a player to know how to play this file, after that you have actual content. So when you only retrieve data from a point that is not 0, you basically remove the metadata, which is crucial.
Want do you want to achieve? Play the audio file from a certain position?
Yeah right! Getting whole of the file needs too long time to wait and request too much of LTE or 5G data usage, so I want to get it only parts of audio like 0:00 ~ 0:10, 1:00 ~ 1:10, 2:00 ~ 2:10,... Then I will use these certain positions to play in the App.
@alexeichhorn Do you need anything I have to provide more information?
If you plug in the unmodified url straight into AVPlayer (no manual downloading) and seek directly to the desired starting position, it shouldn't load unnecessary parts of the file. Or did you try this already?
I tried that and I couldn't play it.π₯²π₯²
Then you mean if I need to play the part of audio File, I have to download all data of the file?
And if it's long time to download, use this code several times
var request = URLRequest(url: externalURL)
request.addValue("bytes=\(startByte)-\(endByte)", forHTTPHeaderField: "Range")
var (data, response) = try await URLSession.shared.data(for: request)
to get each part(ex)0:00~2:00, 2:00~4:00, 4:00~6:00,...) of the audio data. Then append all of the audio data for using in player??
How did you try it?
Works for me. I have an audio app and I'm using AVPlayer
(might not work on AVAudioPlayer
). See this:
let audioStream = try await YouTube(url: URL(string: "https://www.youtube.com/watch?v=xyz")!)
.streams
.filterAudioOnly()
.filter { $0.isNativelyPlayable }
.highestAudioBitrateStream()!
let playerItemAudio = AVPlayerItem(url: audioStream.url)
Hello, Alex.
I asked about extracting part of audio to you, and I solved that problem. Thank You!
But, got something wrong about getting middle part of audio.
I tried
this to get part of audio from youtube video. Although, I successed for get 0:00~0:50 audio easily, I failed to get 2:00~2:50 audio.(Exactly, I got Audio Data, but it couldn;'t played with AVAudioPlayer...)
I can't understand why from 0:00 can be played, and others are impossible...
I always got this Error..ππ