Today, the editor takes time to share with you some questions about uploading large files! Breakpoint continuous transmission and shard upload. Because the file is too large (such as above 1G), the network interruption during the upload process must be considered. The http network request itself has the function of uploading shards. When the transferred files are large, the http protocol will automatically slice (chunk) the file, but this is not the point we are talking about now. What we need to do is to ensure that the uploaded part of the 1G file after the network is interrupted does not have to be retransmitted the next time the network is connected. Therefore, when we upload locally, we need to shard the large files, such as 1024*1024B, that is, we divide the large files into 1M slices for uploading. After the server receives them, we merge these slices into the original file. This is the basic principle of sharding. The interruption of breakpoint transmission requires the local to record the upload status of each piece. I marked the wait loading finish through three states. When the network is interrupted and connected again, upload it from the breakpoint. The server determines whether the file has been uploaded by the file name and total number of slices.
The details are as follows:
1. First obtain the file (audio and video, pictures)
There are two situations: one is to directly obtain it in the album library, and the other is to call the camera. If you are obtained through UIImagePickerView (details are not detailed, there are a lot of them on the Internet), we will find that when you select a video, the compressed page in Figure 1 will appear. Finally, the video obtained by our app is the compressed video (not the original video in the video library. There is a note here. Remember to release it after operating the compressed video. The system will not release it for you. You need to operate it manually, as will be mentioned below). Then, use the protocol method of UIImagePickerView - (void)imagePickerController: (UIImagePickerController*)picker didFinishPickingMediaWithInfo: (NSDictionary*)info to obtain the Info of the video
fileInfo = { UIImagePickerControllerMediaType = ""; UIImagePickerControllerMediaURL = "file:///private/var/mobile/Containers/Data/Application/2AAE9E44-0E6D-4499-9AC3-93D44D8342EA/tmp/trim."; UIImagePickerControllerReferenceURL = "assets-library://asset/?id=DEDA9406-3223-4F87-ABB2-98FB5F5EB9C4&ext=MOV"; }
UIImagePickerControllerMediaType is the type of the selected file, such as KUTTypeImage and KUTTypeMovie. Here we pay attention to the difference between movie and video. One is a video file with sound, the other is a video file without sound, and of course Audio has only sound but no video. UIImagePickerControllerMediaURL is the URL of the video (if it was taken by the camera, then this is the original video taken; if it was selected in the album library, then it is the video generated after compression). Note that this URL does not point to the album library. Through this URL, you can operate this video such as deletion, copy, etc., and you can get the size of the compressed video. UIImagePickerControllerReferenceURL is a URL pointing to the album. The official explanation is an NSURL that references an asset in the AssetsLibrary framework. Through this URL, you can obtain all information about the video, including file name, thumbnail, duration, etc. (through assetsLibraryassetForURL:referenceURLresultBlock: in ALASsetsLibrary).
If it is taken by the camera, pay attention to two ways to save the picture: save the picture to the album
assetsLibrarywriteImageDataToSavedPhotosAlbum:UIImageJPEGRepresentation([infovalueForKey:UIImagePickerControllerOriginalImage],(CGFloat)1.0)metadata:nilcompletionBlock: failureBlock:
Methods for high-fidelity compression of images NSData * UIImageJPEGRepresentation (UIImage *image, CGFloat compressionQuality)
Save video to album: assetsLibrarywriteVideoAtPathToSavedPhotosAlbum:MediaURL completionBlock:failureBlock:
At this point, we have obtained all the required files and file information. What you need to do next is to shard the file.
2. Slice the obtained files
First, I save the obtained file in a class like this
@interface CNFile :NSObject @property(nonatomic,copy)NSString* fileType;//image or movie @property(nonatomic,copy)NSString* filePath;//The file path in the app@property(nonatomic,copy)NSString* fileName;//file name@property(nonatomic,assign)NSIntegerfileSize;//File size@property (nonatomic,assign)NSIntegertrunks;//Total number of films@property(nonatomic,copy)NSString* fileInfo; @property(nonatomic,strong)UIImage* fileImage;// File thumbnail@property(nonatomic,strong) NSMutableArray* fileArr;//Tag the upload status of each piece@end
This way we can operate on each CNFile object.
-(void)readDataWithChunk:(NSInteger)chunk file:(CNFile*)file{
How to get the total number of slices:
intoffset =1024*1024;(The size of each piece is1M) NSIntegerchunks = (%1024==0)?((int)(/1024*1024)):((int)(/(1024*1024) +1)); NSLog(@"chunks = %ld",(long)chunks);
Slice the file and read the data of each slice:
NSData* data; NSFileHandle*readHandle = [NSFileHandlefileHandleForReadingAtPath:]; [readHandleseekToFileOffset:offset * chunk]; data = [readHandlereadDataOfLength:offset]; }
In this way, we get the data to be uploaded for each piece and then ask the server whether the piece already exists
(method-(void)ifHaveData:(NSData*)data WithChunk:(NSInteger)chunk file:(CNFile*)file)
, If it exists, let chunk+1, repeat the above method to read the next slice until the server does not exist, then upload the data of the slice. In this method, pay attention to setting the upload status of the chunk (wait loading finish), which will be related to local judgment whether the file has been uploaded and completed.
The next step is the upload process:
-(void)uploadData:(NSData*) data WithChunk:(NSInteger) chunk file:(CNFile*)file;
After the server returns the movie and uploads successfully, there are many things we need to do:
1) First, set the flag of this film that has been successfully uploaded to finish
[:chunk withObject:@“finish"];
2) Check whether all the flags of all the movies have been finished. If they have finished, it means that the file upload has been completed. Then delete the file, upload the next file or end.
for(NSIntegerj =0; j if(j == chunks || ((j == chunks -1)&&([[j]isEqualToString:@"finish"]))) [medeleteFile:]; [mereadNextFile]; }
3) If not all finished, then see if the flag used by the local chunk is wait
NSLog(@"View the status of the %ld film",chunk+1); for(NSIntegeri = chunk+1;i < chunks;i++) { NSString* flag = [:i]; if([flagisEqualToString:@"wait"]) { [mereadDataWithChunk:ifileName:fileNamefile:file]; break; } }
There can be a 2.5) between steps 2 and 3 to determine whether to suspend uploading
if( ==YES) { //Save the file that has been read to the local area[selfsaveProgressWithChunk:chunk file:file]; return; }
This operation is actually the same as the network interruption process during uploading. In order to continue transmission at the breakpoint, when the network is interrupted or suspended, we must save the current progress so that the previous finished film is skipped when uploading next time.
Then there is another problem. If we upload linearly one piece by one piece, it actually loses the meaning of shard uploading. We should combine multiple threads to make the shard uploading process concurrently execute, and upload multiple pieces at the same time, which improves the upload efficiency and makes full use of network bandwidth.
dispatch_async(dispatch_queue_t queue, ^{ [mereadDataWithChunk: chunk]; })
Finally, please note that after uploading a video, go to the settings to see if the storage space occupied by your app has increased. If you do not process the generated compressed video, you will find that your app has a large space occupied.
Summarize
The above is the fragment upload and breakpoint upload of large iOS files introduced to you by the editor. I hope it will be helpful to you. If you have any questions, please leave me a message and the editor will reply to you in time. Thank you very much for your support for my website!