Luc*_*rti 6 avfoundation avassetexportsession swift
我开始说我花了很多时间在文档,帖子和其他地方搜索,但我无法找到解决这个问题的方法.
我AVAssetExportSession用于导出.mp4存储在AVAsset实例中的文件.我所做的是:
isExportable属性AVAssetexportPresets与AVAsset实例兼容的数组AVAssetExportPreset1920x1080,或者,如果不存在,我尝试导出媒体AVAssetExportPresetPassthrough(仅供参考,100%的时间,我需要的预设总是包含在列表中,但我也尝试了passthrough选项,但它无论如何都不起作用)的outputFileType是AVFileTypeMPEG4,我也试图通过分配.mp4扩展到该文件,但没有什么使得它的工作.我总是收到这个错误
错误域= AVFoundationErrorDomain代码= -11838"操作已停止"UserInfo = {NSUnderlyingError = 0x600000658c30 {错误域= NSOSStatusErrorDomain代码= -12109"(null)"},NSLocalizedFailureReason =此媒体不支持该操作.,NSLocalizedDescription =操作已停止}
下面是我正在使用的代码
func _getDataFor(_ item: AVPlayerItem, completion: @escaping (Data?) -> ()) {
guard item.asset.isExportable else {
completion(nil)
return
}
let compatiblePresets = AVAssetExportSession.exportPresets(compatibleWith: item.asset)
var preset: String = AVAssetExportPresetPassthrough
if compatiblePresets.contains(AVAssetExportPreset1920x1080) { preset = AVAssetExportPreset1920x1080 }
guard
let exportSession = AVAssetExportSession(asset: item.asset, presetName: preset),
exportSession.supportedFileTypes.contains(AVFileTypeMPEG4) else {
completion(nil)
return
}
var tempFileUrl = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0].appendingPathComponent("temp_video_data.mp4", isDirectory: false)
tempFileUrl = URL(fileURLWithPath: tempFileUrl.path)
exportSession.outputURL = tempFileUrl
exportSession.outputFileType = AVFileTypeMPEG4
let startTime = CMTimeMake(0, 1)
let timeRange = CMTimeRangeMake(startTime, item.duration)
exportSession.timeRange = timeRange
exportSession.exportAsynchronously {
print("\(exportSession.error)")
let data = try? Data(contentsOf: tempFileUrl)
_ = try? FileManager.default.removeItem(at: tempFileUrl)
completion(data)
}
}
Run Code Online (Sandbox Code Playgroud)
Luc*_*rti 17
看起来像是AVAsset在一个AVMutableComposition诀窍中转换实例.如果,请,任何人都知道这个工作的原因让我知道.
这是新_getDataFor(_:completion:)方法实现
func _getDataFor(_ item: AVPlayerItem, completion: @escaping (Data?) -> ()) {
guard item.asset.isExportable else {
completion(nil)
return
}
let composition = AVMutableComposition()
let compositionVideoTrack = composition.addMutableTrack(withMediaType: AVMediaTypeVideo, preferredTrackID: CMPersistentTrackID(kCMPersistentTrackID_Invalid))
let compositionAudioTrack = composition.addMutableTrack(withMediaType: AVMediaTypeAudio, preferredTrackID: CMPersistentTrackID(kCMPersistentTrackID_Invalid))
let sourceVideoTrack = item.asset.tracks(withMediaType: AVMediaTypeVideo).first!
let sourceAudioTrack = item.asset.tracks(withMediaType: AVMediaTypeAudio).first!
do {
try compositionVideoTrack.insertTimeRange(CMTimeRangeMake(kCMTimeZero, item.duration), of: sourceVideoTrack, at: kCMTimeZero)
try compositionAudioTrack.insertTimeRange(CMTimeRangeMake(kCMTimeZero, item.duration), of: sourceAudioTrack, at: kCMTimeZero)
} catch(_) {
completion(nil)
return
}
let compatiblePresets = AVAssetExportSession.exportPresets(compatibleWith: composition)
var preset: String = AVAssetExportPresetPassthrough
if compatiblePresets.contains(AVAssetExportPreset1920x1080) { preset = AVAssetExportPreset1920x1080 }
guard
let exportSession = AVAssetExportSession(asset: composition, presetName: preset),
exportSession.supportedFileTypes.contains(AVFileTypeMPEG4) else {
completion(nil)
return
}
var tempFileUrl = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0].appendingPathComponent("temp_video_data.mp4", isDirectory: false)
tempFileUrl = URL(fileURLWithPath: tempFileUrl.path)
exportSession.outputURL = tempFileUrl
exportSession.outputFileType = AVFileTypeMPEG4
let startTime = CMTimeMake(0, 1)
let timeRange = CMTimeRangeMake(startTime, item.duration)
exportSession.timeRange = timeRange
exportSession.exportAsynchronously {
print("\(tempFileUrl)")
print("\(exportSession.error)")
let data = try? Data(contentsOf: tempFileUrl)
_ = try? FileManager.default.removeItem(at: tempFileUrl)
completion(data)
}
}
Run Code Online (Sandbox Code Playgroud)
斯威夫特5:
import Foundation
import AVKit
func getDataFor(_ asset: AVAsset, completion: @escaping (Data?) -> ()) {
guard asset.isExportable,
let sourceVideoTrack = asset.tracks(withMediaType: .video).first,
let sourceAudioTrack = asset.tracks(withMediaType: .audio).first else {
completion(nil)
return
}
let composition = AVMutableComposition()
let compositionVideoTrack = composition.addMutableTrack(withMediaType: .video, preferredTrackID: CMPersistentTrackID(kCMPersistentTrackID_Invalid))
let compositionAudioTrack = composition.addMutableTrack(withMediaType: .audio, preferredTrackID: CMPersistentTrackID(kCMPersistentTrackID_Invalid))
do {
try compositionVideoTrack?.insertTimeRange(CMTimeRangeMake(start: .zero, duration: asset.duration), of: sourceVideoTrack, at: .zero)
try compositionAudioTrack?.insertTimeRange(CMTimeRangeMake(start: .zero, duration: asset.duration), of: sourceAudioTrack, at: .zero)
} catch {
completion(nil)
return
}
let compatiblePresets = AVAssetExportSession.exportPresets(compatibleWith: composition)
var preset = AVAssetExportPresetPassthrough
let preferredPreset = AVAssetExportPreset1920x1080
if compatiblePresets.contains(preferredPreset) {
preset = preferredPreset
}
let fileType: AVFileType = .mp4
guard let exportSession = AVAssetExportSession(asset: composition, presetName: preset),
exportSession.supportedFileTypes.contains(fileType) else {
completion(nil)
return
}
let tempFileUrl = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("temp_video_data")
exportSession.outputURL = tempFileUrl
exportSession.outputFileType = fileType
let startTime = CMTimeMake(value: 0, timescale: 1)
let timeRange = CMTimeRangeMake(start: startTime, duration: asset.duration)
exportSession.timeRange = timeRange
exportSession.exportAsynchronously {
print(tempFileUrl)
print(String(describing: exportSession.error))
let data = try? Data(contentsOf: tempFileUrl)
try? FileManager.default.removeItem(at: tempFileUrl)
completion(data)
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7529 次 |
| 最近记录: |