Swift: сохранить видео из NSURL в рулон камеры пользователя

У меня есть переменная videoURL типа NSURL.

Если я позвоню println(videoURL) это вернуло бы что-то вроде этого:http://files.parsetfss.com/d540f71f-video.mp4

У меня есть кнопка, которая должна взять этот videoURL и сохранить видео в списке пользователя.

Лучшее, что я сделал, это:

UISaveVideoAtPathToSavedPhotosAlbum(videoPath: String!, completionTarget: AnyObject!, completionSelector: Selector, contextInfo: UnsafeMutablePointer<Void>)

Хотя я даже не уверен, сработает ли это или нет, я не могу понять, как конвертировать videoFile:NSURL в videoPath,

Любая помощь приветствуется.

Редактировать:

Следующее неудачно:

UISaveVideoAtPathToSavedPhotosAlbum(videoURL.relativePath, self, nil, nil)

7 ответов

AssetsLibrary устарела

1: импорт фотографий

import Photos

2: Используйте этот код для сохранения видео с URL в библиотеку камеры.

PHPhotoLibrary.sharedPhotoLibrary().performChanges({
             PHAssetChangeRequest.creationRequestForAssetFromVideoAtFileURL(nsUrlToYourVideo)
         }) { saved, error in
             if saved {
                 let alertController = UIAlertController(title: "Your video was successfully saved", message: nil, preferredStyle: .Alert) 
                 let defaultAction = UIAlertAction(title: "OK", style: .Default, handler: nil)
                 alertController.addAction(defaultAction)
                 self.presentViewController(alertController, animated: true, completion: nil)
             }
         }

Свифт 3 и Свифт 4

PHPhotoLibrary.shared().performChanges({
    PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: urlToYourVideo)
}) { saved, error in
    if saved {
        let alertController = UIAlertController(title: "Your video was successfully saved", message: nil, preferredStyle: .alert)
        let defaultAction = UIAlertAction(title: "OK", style: .default, handler: nil)
        alertController.addAction(defaultAction)
        self.present(alertController, animated: true, completion: nil)
    }
}

Принятый ответ больше не работает с Swift 3.0 и iOS 10.

Во-первых, вам нужно установить следующее разрешение в plist-файле вашего приложения:

Конфиденциальность - Фото Библиотека Описание использования

Предоставьте строку, которая представляется пользователю, объясняющую, почему вы запрашиваете разрешение.

Далее импортируем фотографии:

import Photos

Наконец, вот обновленный код для Swift 3.0:

PHPhotoLibrary.shared().performChanges({
    PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: fileURL)
}) { saved, error in
    if saved {
        let alertController = UIAlertController(title: "Your video was successfully saved", message: nil, preferredStyle: .alert)
        let defaultAction = UIAlertAction(title: "OK", style: .default, handler: nil)
        alertController.addAction(defaultAction)
        self.present(alertController, animated: true, completion: nil)
    }
}

Чтобы сохранить видео из NSURL в рулон камеры пользователя

func video(videoPath: NSString, didFinishSavingWithError error: NSError?, contextInfo info: AnyObject) 
 {
    if let _ = error {
       print("Error,Video failed to save")
    }else{
       print("Successfully,Video was saved")
    }
}







func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {

    if let conversationField = self.conversation {

      if (mediaType?.isEqual((kUTTypeMovie as NSString) as String))!
        {
            let theVideoURL: URL? = (info[UIImagePickerControllerMediaURL] as? URL)

            if (UIVideoAtPathIsCompatibleWithSavedPhotosAlbum((theVideoURL?.path)!))
            {
                UISaveVideoAtPathToSavedPhotosAlbum((theVideoURL?.path)!, self, #selector(ConversationDetailsViewController.video(videoPath:didFinishSavingWithError:contextInfo:)), nil)
            }   
   }
   self.dismiss(animated: true, completion: nil)
}

Ссылка от:: https://www.raywenderlich.com/94404/play-record-merge-videos-ios-swift

Попробуйте вместо этого для сохранения видео в библиотеке фотографий в Swift 4.2 и выше.

func requestAuthorization(completion: @escaping ()->Void) {
        if PHPhotoLibrary.authorizationStatus() == .notDetermined {
            PHPhotoLibrary.requestAuthorization { (status) in
                DispatchQueue.main.async {
                    completion()
                }
            }
        } else if PHPhotoLibrary.authorizationStatus() == .authorized{
            completion()
        }
    }



func saveVideoToAlbum(_ outputURL: URL, _ completion: ((Error?) -> Void)?) {
        requestAuthorization {
            PHPhotoLibrary.shared().performChanges({
                let request = PHAssetCreationRequest.forAsset()
                request.addResource(with: .video, fileURL: outputURL, options: nil)
            }) { (result, error) in
                DispatchQueue.main.async {
                    if let error = error {
                        print(error.localizedDescription)
                    } else {
                        print("Saved successfully")
                    }
                    completion?(error)
                }
            }
        }
    }

Использование функции

self.saveVideoToAlbum(/* pass your final url to save */) { (error) in
                        //Do what you want 
                    }

Не забудьте импортировать фотографии и добавить описание использования фото-библиотеки в свой info.plist

устарел с iOS 9

1: импортировать AssetsLibrary

import AssetsLibrary

2: Используйте этот код для сохранения видео с URL в библиотеку камеры.

ALAssetsLibrary().writeVideoAtPathToSavedPhotosAlbum(outputFileURL, completionBlock: nil)

Современная версия, использующая await/async и Swift 5.

      import Foundation
import Photos

class PhotoLibrary {

    class func requestAuthorizationIfNeeded() async -> PHAuthorizationStatus {
        let status = PHPhotoLibrary.authorizationStatus(for: .readWrite)

        if status == .notDetermined {
            return await PHPhotoLibrary.requestAuthorization(for: .readWrite)
        } else {
            return status
        }
    }

    enum PhotoLibraryError: Error {
        case insufficientPermissions
        case savingFailed
    }

    class func saveVideoToCameraRoll(url: URL) async throws {

        let authStatus = await requestAuthorizationIfNeeded()

        guard authStatus == .authorized else {
            throw PhotoLibraryError.insufficientPermissions
        }

        do {
            try await PHPhotoLibrary.shared().performChanges {
                PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: url)
            }
        } catch {
            throw PhotoLibraryError.savingFailed
        }
    }
}

Затем используйте его следующим образом:

      do {
    try await PhotoLibrary.saveVideoToCameraRoll(url: url)
} catch {
    // Handle error
}

Просто используйте его и вставьте URL своего видео:

PHPhotoLibrary.sharedPhotoLibrary().performChanges({ () -> Void in

    let createAssetRequest: PHAssetChangeRequest = PHAssetChangeRequest.creationRequestForAssetFromVideoAtFileURL(NSURL(string: /* your url */)!)!
    createAssetRequest.placeholderForCreatedAsset

    }) { (success, error) -> Void in
        if success {

            //popup alert success
        }
        else {
           //popup alert unsuccess
        }
}
Другие вопросы по тегам