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
}
}