簡體   English   中英

AVAssetExportSession無法從照片庫轉換.mov。為什么?

[英]AVAssetExportSession fails to convert .mov from photo library. Why?

場景:
我希望減少iTouch照片庫中單個視頻的大小。

1.從庫中收集視頻資產。
2.獲取PHAsset的縮略圖 - 有效。
3.從庫中獲取實際視頻。
4.從庫中請求AVAssetForVideo。
5.通過ExportSessions轉換視頻...加載各種參數。
6.嘗試將導出運行到tmp目錄以供使用。
*失敗*

這是調試輸出:

在此輸入圖像描述

這是錯誤消息:
在此輸入圖像描述

func getVideoFromPhotoLibrary() {
    let videoAssets =  PHAsset.fetchAssetsWithMediaType(.Video, options:nil)

    videoAssets.enumerateObjectsUsingBlock {
        (obj:AnyObject!, index:Int, stop:UnsafeMutablePointer<ObjCBool>) in
        let mySize = CGSizeMake(120,120)
        let myAsset = obj as! PHAsset

        let imageManager = PHImageManager.defaultManager()
        var myVideo:BlissMedium?

        // Request the poster frame or the image of the video
        imageManager.requestImageForAsset(myAsset, targetSize:mySize, contentMode: .AspectFit, options: nil) {
            (imageResult, info) in
            let thumbnail = UIImage(named:"videoRed")
            myVideo = BlissMedium(blissImage: imageResult, creationDate:myAsset.creationDate)
            myVideo!.mediumType = .video
        }

        // Actual Video:
        imageManager.requestAVAssetForVideo(myAsset, options: nil, resultHandler: {result, audio, info in
            let asset = result as! AVURLAsset
            let mediaURL = asset.URL
            let session = AVAssetExportSession(asset: asset, presetName: AVAssetExportPresetMediumQuality)
            let filename = "composition.mp4"


            session.outputURL = NSURL(string: NSTemporaryDirectory());
            session.outputFileType = AVFileTypeQuickTimeMovie;

            session.exportAsynchronouslyWithCompletionHandler({ () -> Void in
                dispatch_async(dispatch_get_main_queue(), {
                    if session.status == AVAssetExportSessionStatus.Completed {
                        println("Success")
                    }
                    else {
                        println(session.error?.localizedDescription)
                        //The requested URL was not found on this server.
                    }
                })
            })
        })

        if nil != myVideo {
            self.gBlissVideoMedia.append(myVideo!)
        }
    }
}


我檢查確保目標路徑/文件存在; 然后我添加了'AVFileTypeMPEG4'輸出類型以匹配預期的.mp4:

let targetDir = createTempDirectory("bliss/composition.mp4") as String?

if NSFileManager.defaultManager().fileExistsAtPath(targetDir!) {
    println("*** file exists! ***")
} else {
    return
}
session.outputURL = NSURL(string: targetDir!);
session.outputFileType = AVFileTypeMPEG4

我還有問題:

* 文件已存在! *

可選(“操作無法完成”)

我究竟做錯了什么; 少了什么東西?


更新:
我能夠在Objective-C中成功運行導出到我的NSHomeDirectory()vs NSTemporaryDictory()。

但是......用Swift編寫的相同代碼失敗了。

我注意到Swift中目標輸出的絕對路徑發生了變化,在Objective-C中找不到:
在此輸入圖像描述

也許這是一個Swift 1.2 bug ???

我不確定你是否可以保存在temp目錄的根目錄中,我通常使用這個函數來創建一個我可以使用的新臨時目錄:

func createTempDirectory(myDir: String) -> String? {
    let tempDirectoryTemplate = NSTemporaryDirectory().stringByAppendingPathComponent(myDir)

    let fileManager = NSFileManager.defaultManager()

    var err: NSErrorPointer = nil
    if fileManager.createDirectoryAtPath(tempDirectoryTemplate, withIntermediateDirectories: true, attributes: nil, error: err) {
        return tempDirectoryTemplate
    } else {
        return nil
    }
}

嘗試在此函數返回的目錄中進行轉換。

我希望能幫到你!

我不太清楚代碼的最后部分是做什么的,在哪里可以找出文件是否存在。 您找到的是哪個文件?

由於我不明白,這可能是無關緊要的,但在你最頂層的代碼中,我注意到你將filename設置為composition.mp4 ,但讓outputURLNSURL(string: NSTemporaryDirectory()) 隨着我缺乏迅捷的我可能失去了一些東西,但它好像你不使用的文件名都,並試圖寫入文件文件夾,在我看來。 我相信設置一個合適的URL可能會解決問題,但我不確定。 一個Objective-c例子可能是:

NSURL * outputURL = [[NSURL alloc] 
    initFileURLWithPath:[NSString pathWithComponents:
    @[NSTemporaryDirectory(), @"composition.mp4"]]];

outputURL應該指向實際文件,而不是它所在的文件夾。我認為..

無論如何,如果這不起作用,我也有其他一些想法。 你在實際的設備上試過嗎? 模擬器可能存在問題。

還有,遺憾的是,我已經在不同的根問題上無數次地得到了錯誤-12780 ,所以這並沒有多大幫助。

並且,我看到你檢查if session.status == AVAssetExportSessionStatus.Completed ,你檢查了實際狀態是什么嗎? 它是.Failed ,還是.Unknown 有幾種狀態。

這可能是一個很長的鏡頭,但在我的一個應用程序中,我使用相機捕獲視頻/音頻,然后使用AVAssetExportSession對其進行編碼/轉換。 開始錄制時以及錄制(導出)后都會出現奇怪的錯誤。 我發現我可以改變AVAudioSession ,這顯然與設備如何處理媒體有關。 我不知道如何使用Swift,但這是我的代碼(在相關視圖的viewDidAppear中)

NSError *error;
AVAudioSession *aSession = [AVAudioSession sharedInstance];
[aSession setCategory:AVAudioSessionCategoryPlayAndRecord error:&error];

[aSession setMode:AVAudioSessionModeVideoRecording error:&error];
[aSession setActive: YES error: &error];

PlayAndRecord類別允許我更快地啟動相機,以及擺脫偶爾掛起的AVAssetExportSessionStatus.Unknown和偶爾崩潰.Failed (它也拋出-12780 )。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM