移动并修复手机iOS上录制的video的moovprimefaces

问题是如何find并移动iOS设备上logging的.mov文件的moovprimefaces,以便通过http进行stream式处理。 有一种方法可以做到这一点,但需要将其导出到文件中,理论上使您可以将整个文件复制过来,然后就可以对其进行stream式处理。

有没有其他方法可以做到这一点?

  • 使用iOS AV Foundation框架和几行Objective-C(您也可以将MOV转换为MP4,因为Android无法读取MOV):

    所以使用这个代码没有缓冲区播放stream畅的video从实时url的作品,但在上传video到您的服务器之前使用此代码并转换您的video,并在上传后。 所以video就是像Snapchat一样播放video而没有任何负载。

    不要忘了把这个框架添加到你的Project.😊

#import <AVFoundation/AVAsset.h> #import <AVFoundation/AVAssetExportSession.h> #import <AVFoundation/AVMediaFormat.h> 
 + (void) convertVideoToMP4AndFixMooV: (NSString*)filename toPath:(NSString*)outputPath { NSURL *url = [NSURL fileURLWithPath:filename]; AVAsset *avAsset = [AVURLAsset URLAssetWithURL:url options:nil]; AVAssetExportSession *exportSession = [AVAssetExportSession exportSessionWithAsset:avAsset presetName:AVAssetExportPresetPassthrough]; exportSession.outputURL = [NSURL fileURLWithPath:outputPath]; exportSession.outputFileType = AVFileTypeAppleM4V; // This should move the moov atom before the mdat atom, // hence allow playback before the entire file is downloaded exportSession.shouldOptimizeForNetworkUse = YES; [exportSession exportAsynchronouslyWithCompletionHandler: ^{ if (AVAssetExportSessionStatusCompleted == exportSession.status) {} else if (AVAssetExportSessionStatusFailed == exportSession.status) { NSLog(@"AVAssetExportSessionStatusFailed"); } else { NSLog(@"Export Session Status: %d", exportSession.status); } }]; } 

下面是我编辑和编写的一个方法的代码,以便与iOS一起查找,然后将moovprimefaces写入特定的位置,然后在您拥有video文件的这两部分之后,您只需访问video文件的字节从FTYPprimefaces结束的位置(查看标记为start_offset和last_offset的variables),并进行stream式处理。

 - (NSString *)fixForFastPlayback:(char*)dest:(ALAsset*)selected { FILE *infile = NULL; FILE *outfile = NULL; uint32_t atom_type = 0; uint64_t atom_size = 0; uint64_t atom_offset = 0; uint64_t last_offset; uint64_t moov_atom_size; uint64_t ftyp_atom_size = 0; uint64_t i, j; uint32_t offset_count; uint64_t current_offset; uint64_t start_offset = 0; ALAssetRepresentation * rep = [[selected defaultRepresentation] retain]; int bufferSize = 8192; // or use 8192 size as read from other posts int read = 0; NSError * err = nil; uint8_t * buffer = calloc(bufferSize, sizeof(*buffer)); uint8_t * ftyp_atom; /* traverse through the atoms in the file to make sure that 'moov' is * at the end */ int asset_offset = 0; while (asset_offset < [rep size]) { read = [rep getBytes:buffer fromOffset:asset_offset length:ATOM_PREAMBLE_SIZE error:&err]; asset_offset += read; if (err != nil) { NSLog(@"Error: %@ %@", err, [err userInfo]); } atom_size = (uint32_t)BE_32(&buffer[0]); atom_type = BE_32(&buffer[4]); /* keep ftyp atom */ if (atom_type == FTYP_ATOM) //no idea what an atom is, maybe a header or some sort of meta data or a file marker { ftyp_atom_size = atom_size; ftyp_atom = calloc(ftyp_atom_size, sizeof(*buffer)); if (!ftyp_atom) { printf ("could not allocate %"PRIu64" byte for ftyp atom\n", atom_size); } asset_offset -= ATOM_PREAMBLE_SIZE; read = [rep getBytes:ftyp_atom fromOffset:asset_offset length:ftyp_atom_size error:&err]; asset_offset += read; start_offset = asset_offset; } else { asset_offset += (atom_size - ATOM_PREAMBLE_SIZE); } printf("%c%c%c%c %10"PRIu64" %"PRIu64"\n", (atom_type >> 24) & 255, (atom_type >> 16) & 255, (atom_type >> 8) & 255, (atom_type >> 0) & 255, atom_offset, atom_size); if ((atom_type != FREE_ATOM) && (atom_type != JUNK_ATOM) && (atom_type != MDAT_ATOM) && (atom_type != MOOV_ATOM) && (atom_type != PNOT_ATOM) && (atom_type != SKIP_ATOM) && (atom_type != WIDE_ATOM) && (atom_type != PICT_ATOM) && (atom_type != UUID_ATOM) && (atom_type != FTYP_ATOM)) { printf ("encountered non-QT top-level atom (is this a Quicktime file?)\n"); break; } atom_offset += atom_size; /* The atom header is 8 (or 16 bytes), if the atom size (which * includes these 8 or 16 bytes) is less than that, we won't be * able to continue scanning sensibly after this atom, so break. */ if (atom_size < 8) break; } if (atom_type != MOOV_ATOM) { printf ("last atom in file was not a moov atom\n"); free(ftyp_atom); fclose(infile); return 0; } asset_offset = [rep size]; asset_offset -= atom_size; last_offset = asset_offset; moov_atom_size = atom_size; uint8_t * moov_atom = calloc(moov_atom_size, sizeof(*buffer)); if (!moov_atom) { printf ("could not allocate %"PRIu64" byte for moov atom\n", atom_size); } read = [rep getBytes:moov_atom fromOffset:asset_offset length:moov_atom_size error:&err]; asset_offset += read; /* this utility does not support compressed atoms yet, so disqualify * files with compressed QT atoms */ if (BE_32(&moov_atom[12]) == CMOV_ATOM) { printf ("this utility does not support compressed moov atoms yet\n"); } /* crawl through the moov chunk in search of stco or co64 atoms */ for (i = 4; i < moov_atom_size - 4; i++) { atom_type = BE_32(&moov_atom[i]); if (atom_type == STCO_ATOM) { printf (" patching stco atom...\n"); atom_size = BE_32(&moov_atom[i - 4]); if (i + atom_size - 4 > moov_atom_size) { printf (" bad atom size\n"); } offset_count = BE_32(&moov_atom[i + 8]); for (j = 0; j < offset_count; j++) { current_offset = BE_32(&moov_atom[i + 12 + j * 4]); current_offset += moov_atom_size; moov_atom[i + 12 + j * 4 + 0] = (current_offset >> 24) & 0xFF; moov_atom[i + 12 + j * 4 + 1] = (current_offset >> 16) & 0xFF; moov_atom[i + 12 + j * 4 + 2] = (current_offset >> 8) & 0xFF; moov_atom[i + 12 + j * 4 + 3] = (current_offset >> 0) & 0xFF; } i += atom_size - 4; } else if (atom_type == CO64_ATOM) { printf (" patching co64 atom...\n"); atom_size = BE_32(&moov_atom[i - 4]); if (i + atom_size - 4 > moov_atom_size) { printf (" bad atom size\n"); } offset_count = BE_32(&moov_atom[i + 8]); for (j = 0; j < offset_count; j++) { current_offset = BE_64(&moov_atom[i + 12 + j * 8]); current_offset += moov_atom_size; moov_atom[i + 12 + j * 8 + 0] = (current_offset >> 56) & 0xFF; moov_atom[i + 12 + j * 8 + 1] = (current_offset >> 48) & 0xFF; moov_atom[i + 12 + j * 8 + 2] = (current_offset >> 40) & 0xFF; moov_atom[i + 12 + j * 8 + 3] = (current_offset >> 32) & 0xFF; moov_atom[i + 12 + j * 8 + 4] = (current_offset >> 24) & 0xFF; moov_atom[i + 12 + j * 8 + 5] = (current_offset >> 16) & 0xFF; moov_atom[i + 12 + j * 8 + 6] = (current_offset >> 8) & 0xFF; moov_atom[i + 12 + j * 8 + 7] = (current_offset >> 0) & 0xFF; } i += atom_size - 4; } } outfile = fopen(dest, "wb"); NSLog(@"%llu",last_offset); //global variables to be used when returning the actual data start_offset_not_c = start_offset; last_offset_not_c = last_offset; if (ftyp_atom_size > 0) { printf ("writing ftyp atom...\n"); if (fwrite(ftyp_atom, ftyp_atom_size, 1, outfile) != 1) { perror(dest); } } printf ("writing moov atom...\n"); if (fwrite(moov_atom, moov_atom_size, 1, outfile) != 1) { perror(dest); } fclose(outfile); free(ftyp_atom); free(moov_atom); ftyp_atom = NULL; moov_atom = NULL; return [NSString stringWithCString:dest encoding:NSStringEncodingConversionAllowLossy]; } 

请享用!