Reputation: 16189
I want to get the right bitrate of a video which shot by my iPhone. But I got the error:
Failed to load asset tracks: The operation could not be completed
here is my code:
Movie.swift (get the url)
struct Movie: Transferable {
let url: URL
static var transferRepresentation: some TransferRepresentation {
FileRepresentation(contentType: .data) { movie in
SentTransferredFile(movie.url)
} importing: { received in
return Self.init(url: received.file)
}
}
}
ContentView.swift
struct ContentView: View {
@State private var selectedItem: PhotosPickerItem?
@State var bitrate: Float?
var body: some View {
VStack {
PhotosPicker("Select video", selection: $selectedItem, matching: .videos)
if let bitrate {
Text("\(bitrate)")
}
}
.onChange(of: selectedItem) { _ in
Task {
if let movie = try? await selectedItem?.loadTransferable(type: Movie.self) {
do {
bitrate = try await getVb(from: movie.url)
print(bitrate)
} catch {
print(error)
}
}
}
}
}
func getVb(from url: URL) async throws -> Float? {
let asset = AVAsset(url: url)
let videoTrack = try await asset.loadTracks(withMediaType: .video)
let bit = try await videoTrack.first?.load(.estimatedDataRate)
return bit
}
}
Any suggestions? thanks.
EDIT 1
Thanks @lorem ipsum 's point. Then I moved the get bitrate into the importing
closure, the bitrate is larger.
static var transferRepresentation: some TransferRepresentation {
FileRepresentation(contentType: .data) { movie in
SentTransferredFile(movie.url)
} importing: { received in
let bitrate = try? await getVb(from: received.file)
print(bitrate)
func getVb(from url: URL) async throws -> Float? {
let asset = AVAsset(url: url)
let videoTrack = try await asset.loadTracks(withMediaType: .video)
let bit = try await videoTrack.first?.load(.estimatedDataRate)
return bit
}
return Self.init(url: received.file)
}
}
The print is 4231527.5
actually the size is 1356000
bps.
Then I tried copy the item to another path.
static var transferRepresentation: some TransferRepresentation {
FileRepresentation(contentType: .data) { movie in
SentTransferredFile(movie.url)
} importing: { received in
let cacheURL = URL.cachesDirectory.appending(path: received.file.lastPathComponent)
if FileManager.default.fileExists(atPath: cacheURL.path()) {
try FileManager.default.removeItem(at: cacheURL)
}
try FileManager.default.copyItem(at: received.file, to: cacheURL)
return Self.init(url: cacheURL)
}
The pirate is 23000497
bps.
It's interesting why the size is larger? thanks!
Upvotes: 0
Views: 46