diff --git a/Sources/Navigator/Audiobook/PublicationMediaLoader.swift b/Sources/Navigator/Audiobook/PublicationMediaLoader.swift index 714b5df4e..bba1fdb41 100644 --- a/Sources/Navigator/Audiobook/PublicationMediaLoader.swift +++ b/Sources/Navigator/Audiobook/PublicationMediaLoader.swift @@ -84,7 +84,7 @@ final class PublicationMediaLoader: NSObject, AVAssetResourceLoaderDelegate { /// Terminates and removes the given loading request, cancelling it if necessary. private func finishRequest(_ request: AVAssetResourceLoadingRequest) { guard - let href = request.href, + let href = request.request.url?.audioHREF, var reqs = requests[href], let index = reqs.firstIndex(where: { req, _ in req == request }) else { @@ -106,7 +106,7 @@ final class PublicationMediaLoader: NSObject, AVAssetResourceLoaderDelegate { // MARK: - AVAssetResourceLoaderDelegate func resourceLoader(_ resourceLoader: AVAssetResourceLoader, shouldWaitForLoadingOfRequestedResource loadingRequest: AVAssetResourceLoadingRequest) -> Bool { - guard let href = loadingRequest.href else { + guard let href = loadingRequest.request.url?.audioHREF else { return false } @@ -163,22 +163,16 @@ final class PublicationMediaLoader: NSObject, AVAssetResourceLoaderDelegate { private let schemePrefix = "r2" -private extension AVAssetResourceLoadingRequest { - var href: String? { - guard let url = request.url?.absoluteURL, url.scheme.rawValue.hasPrefix(schemePrefix) == true else { +extension URL { + var audioHREF: String? { + guard let url = absoluteURL, url.scheme.rawValue.hasPrefix(schemePrefix) == true else { return nil } // The URL can be either: - // * r2file://directory/local-file.mp3 + // * r2:relative/file.mp3 + // * r2file:///directory/local-file.mp3 // * r2http(s)://domain.com/external-file.mp3 - switch url.scheme.rawValue { - case "r2file", "r2": - return url.path - case "r2http", "r2https": - return url.string.removingPrefix(schemePrefix) - default: - return nil - } + return url.string.removingPrefix(schemePrefix).removingPrefix(":") } } diff --git a/Tests/NavigatorTests/Audio/PublicationMediaLoaderTests.swift b/Tests/NavigatorTests/Audio/PublicationMediaLoaderTests.swift new file mode 100644 index 000000000..327c83203 --- /dev/null +++ b/Tests/NavigatorTests/Audio/PublicationMediaLoaderTests.swift @@ -0,0 +1,30 @@ +// +// Copyright 2024 Readium Foundation. All rights reserved. +// Use of this source code is governed by the BSD-style license +// available in the top-level LICENSE file of the project. +// + +@testable import R2Navigator +import XCTest + +class PublicationMediaLoaderTests: XCTestCase { + func testURLToHREF() { + XCTAssertEqual(URL(string: "r2:relative/file.mp3")!.audioHREF, "relative/file.mp3") + XCTAssertEqual(URL(string: "r2:/absolute/file.mp3")!.audioHREF, "/absolute/file.mp3") + XCTAssertEqual(URL(string: "r2file:///directory/file.mp3")!.audioHREF, "file:///directory/file.mp3") + XCTAssertEqual(URL(string: "r2http:///domain.com/file.mp3")!.audioHREF, "http:///domain.com/file.mp3") + XCTAssertEqual(URL(string: "r2https:///domain.com/file.mp3")!.audioHREF, "https:///domain.com/file.mp3") + + // Encoded characters + XCTAssertEqual(URL(string: "r2:relative/a%20file.mp3")!.audioHREF, "relative/a%20file.mp3") + XCTAssertEqual(URL(string: "r2:/absolute/a%20file.mp3")!.audioHREF, "/absolute/a%20file.mp3") + XCTAssertEqual(URL(string: "r2file:///directory/a%20file.mp3")!.audioHREF, "file:///directory/a%20file.mp3") + XCTAssertEqual(URL(string: "r2http:///domain.com/a%20file.mp3")!.audioHREF, "http:///domain.com/a%20file.mp3") + XCTAssertEqual(URL(string: "r2https:///domain.com/a%20file.mp3")!.audioHREF, "https:///domain.com/a%20file.mp3") + + // Ignores if the r2 prefix is missing. + XCTAssertNil(URL(string: "relative/file.mp3")!.audioHREF) + XCTAssertNil(URL(string: "file:///directory/file.mp3")!.audioHREF) + XCTAssertNil(URL(string: "http:///domain.com/file.mp3")!.audioHREF) + } +}