I am currently working on a method to upload videos short videos (10-30sec) to my data base, and was questioning if is possible to convert a video from the local gallery to base64, at the moment I get the video using the imagePickerController as you can see in this code:
func imagePickerController(_ picker: UIImagePickerController,
didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
//Here is save the video URL
let url = info[.mediaURL] as? URL
//Here goes the code to convert this video URL to base64...
self.dismiss(animated: true)
}
I was also questioning if is viable to save the video to base64 and send it in the body of my post request or should I use other way to upload my video in the server?
I am open to any recommendation, thanks
2
Answers
For upload file to server use
Multipart/form-data
, because Base64 has 4/3 of original file sizeI would advise against base64 encoding a video.
The asset is already so large that:
You want to prevent base64 from making the asset even larger (and, therefore, the upload even slower); and
You probably want to avoid ever loading the whole asset into memory at any given time, anyway (i.e. avoid using a
Data
in the process of building this upload request). The standard base-64 encodingData
methods effectively require that you have the entire asset in memory to perform the base-64 encoding, and you will also have the base-64 string in memory at the same time, too.E.g., using the standard base-64 encoding
Data
method for a 50 mb video will probably spike memory up to 116 mb, at least.A
multipart/form-data
request is the standard approach (allows embedding of binary payload and sending of additional fields). Be careful, though, as most examples that you’ll find online build aData
which it then sends, which probably is not prudent. Write it to a file without ever trying to load the whole asset in RAM at any given time. Then perform a file-based upload task to send this to your server.For example if you wanted to create this multipart request yourself, you could do something like the following:
and
and
Then you can do things like (in iOS 15):
Or, in earlier Swift versions:
Here, although I uploaded two 55mb videos, total allocations never exceeded 8mb (and some of that appears to be memory cached by the image picker, itself). I repeated it twice to illustrate that the memory does not continue to grow for each subsequent upload.
(The green intervals are the time spent in the image/video picker and the associated compression of the video. The red interval is the time of the actual upload. This way you can correlate the process with the memory usage.)