2016-02-18 10 views
10

Attualmente sto visualizzando un video nella mia app e voglio che l'utente possa salvarlo nella sua galleria di dispositivi/album fotografico/rullino fotografico. qui è quello che sto facendo, ma il video non viene salvato nell'album:/Swift - Scarica un video dall'URL distante e salvalo in un album fotografico

func downloadVideo(videoImageUrl:String) 
{ 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), { 
     //All stuff here 

     print("downloadVideo"); 
     let url=NSURL(string: videoImageUrl); 
     let urlData=NSData(contentsOfURL: url!); 

     if((urlData) != nil) 
     { 
      let documentsPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0]; 

      let fileName = videoImageUrl; //.stringByDeletingPathExtension 

      let filePath="\(documentsPath)/\(fileName)"; 

      //saving is done on main thread 

      dispatch_async(dispatch_get_main_queue(), {() -> Void in 

       urlData?.writeToFile(filePath, atomically: true); 
       print("videoSaved"); 
      }) 

     } 
    }) 

} 

I'va anche prendere in considerazione questo:

let url:NSURL = NSURL(string: fileURL)!; 

    PHPhotoLibrary.sharedPhotoLibrary().performChanges({ 
     let assetChangeRequest = PHAssetChangeRequest.creationRequestForAssetFromVideoAtFileURL(url); 
     let assetPlaceHolder = assetChangeRequest!.placeholderForCreatedAsset; 
     let albumChangeRequest = PHAssetCollectionChangeRequest(forAssetCollection: self.assetCollection) 
     albumChangeRequest!.addAssets([assetPlaceHolder!]) 
     }, completionHandler: saveVideoCallBack) 

Ma ho l'errore "Impossibile creare dati da file (null) ". Il mio "assetChangeRequest" è nullo. Non capisco come il mio url è valido e quando vado a esso con un browser, scarica un file di tempo veloce.

Se qualcuno può aiutarmi, sarebbe apprezzato! Sto usando Swift e il targeting di iOS 8.0 min.

+1

Se si desidera salvare un file a rullino fotografico, dare un'occhiata a classi PHPhotoLibrary e il metodo '' creationRequestForAssetFromVideoAtFileURL' di PHAssetChangeRequest' – Nimble

+0

Nel doc qui: https://developer.apple.com/library/prerelease/ios/documentation/Photos/Reference/PHAssetChangeRequest_Class/index.html#//apple_ref/occ/clm/PHAssetChangeRequest/creationRequestForAssetFromVideoAtFileURL, non lo faccio capire cos'è fileURL. –

+0

'fileURL' è un collegamento a un file video. Hai provato a usare 'filePath' come' fileURL'? Potrebbe essere simile a questo 'PHAssetChangeRequest.creationRequestForAssetFromVideoAtFileURL (NSURL (fileURLWithPath: filePath))' – Nimble

risposta

21

Aggiornamento

voluto aggiornare la risposta per Swift 3 utilizzando URLSession e capito che la risposta esiste già in argomento correlato here. Usalo.

risposta originale

Il codice sotto salva un file video da Rullino fotografico. Ho riutilizzato il tuo codice con una piccola modifica - Ho rimosso let fileName = videoImageUrl; perché porta a un percorso file errato.

Ho testato questo codice e salvato l'asset nel rullino fotografico. Hai chiesto cosa inserire in creationRequestForAssetFromVideoAtFileURL - inserisci un collegamento al file video scaricato come nell'esempio seguente.

let videoImageUrl = "http://www.sample-videos.com/video/mp4/720/big_buck_bunny_720p_1mb.mp4" 

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), { 
     let url = NSURL(string: videoImageUrl); 
     let urlData = NSData(contentsOfURL: url!); 
     if(urlData != nil) 
     { 
      let documentsPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0]; 
      let filePath="\(documentsPath)/tempFile.mp4"; 
      dispatch_async(dispatch_get_main_queue(), { 
       urlData?.writeToFile(filePath, atomically: true); 
       PHPhotoLibrary.sharedPhotoLibrary().performChanges({ 
        PHAssetChangeRequest.creationRequestForAssetFromVideoAtFileURL(NSURL(fileURLWithPath: filePath)) 
       }) { completed, error in 
        if completed { 
         print("Video is saved!") 
        } 
       } 
      }) 
     } 
    }) 
+1

Grazie mille! Sei un salvatore di vita :) –

+0

@Nimble hai idea che possiamo archiviare i video direttamente nella libreria di foto senza memorizzarli prima nella cartella documenti? – Urmi

+0

Si sta salvando il file nella directory dei documenti ma non viene eliminato in seguito (almeno in questo codice). Si dovrebbe anche prendere in considerazione la pulizia. Se si desidera la pulizia automatica, perché non salvare invece nella directory temporanea? Oppure, se lo vuoi manualmente, fai la pulizia nel blocco di completamento. – yoninja

10

Swift 3 versione del codice da @Nimble:

DispatchQueue.global(qos: .background).async { 
    if let url = URL(string: urlString), 
     let urlData = NSData(contentsOf: url) 
    { 
     let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]; 
     let filePath="\(documentsPath)/tempFile.mp4" 
     DispatchQueue.main.async { 
      urlData.write(toFile: filePath, atomically: true) 
      PHPhotoLibrary.shared().performChanges({ 
       PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: URL(fileURLWithPath: filePath)) 
      }) { completed, error in 
       if completed { 
        print("Video is saved!") 
       } 
      } 
     } 
    } 
} 
+0

hai idea che possiamo archiviare i video direttamente nella libreria di foto senza memorizzarli prima nella cartella documenti? – Urmi

+0

Non che io sappia. Si dovrebbe guardare la libreria di foto come un database, quindi il download in un "database" non ha senso. –

+0

Ok. ma hai idea di quanti dati (GB) possiamo memorizzare per un'applicazione specifica. Proprio come WhatsApp memorizza tutte le immagini e i video nella libreria di foto. nello stesso tempo li sta salvando nella cartella documenti? \t perché sto sviluppando applicazioni simili per scaricare immagini e video da sever e salvarlo nella cartella documenti. – Urmi