IPhone: программно сжимать записанное видео для совместного использования?
Я использовал представление наложения при вызове камеры перед записью видео.
pickerController.cameraOverlayView =myOverlay;
Запись видео и сохранение видео в альбом после записи видео и обмена по электронной почте и т.д. Все работает нормально.
Если я использую качество видео как "Высокое качество", тогда записанное видео стало огромным размером. Например, если я записываю видео в течение 30 секунд с высоким качеством, записанное видео становится около 30 - 40 мб.
pickerController.videoQuality = UIImagePickerControllerQualityTypeHigh;
Как мне настроить сжатие высококачественного записанного видео до его совместного использования, например, как Apple делает со встроенным видеомагнитофоном?
Пожалуйста, помогите мне решить эту проблему.
Спасибо!
ОБНОВЛЕНО:
Это то, что я делаю в последнее время, но все равно не добился успеха: хочу сжать записанное видео, которое приходит в файл didFinishPickingMediaWithInfo, и сохранить в том же самом видео-видео самого альбома, нигде. Я тестировал одно и то же видео, сжатое до очень небольшого размера, когда я выбираю из библиотеки фотографий, но то же видео, снятое с камеры и появившееся через didFinishPickingMediaWithInfo, не сжато, хотя я использовал код AVAssetExportSession ниже.
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{
NSString *mediaType = [info objectForKey:UIImagePickerControllerMediaType];
if ([mediaType isEqualToString:(NSString *)kUTTypeMovie])
{
NSURL *videoURL = [info objectForKey:UIImagePickerControllerMediaURL];
NSString *urlPath = [videoURL path];
if ([[urlPath lastPathComponent] isEqualToString:@"capturedvideo.MOV"])
{
if (UIVideoAtPathIsCompatibleWithSavedPhotosAlbum (urlPath))
{
[self copyTempVideoToMediaLibrary :urlPath];
}
else
{
NSLog(@"Video Capture Error: Captured video cannot be saved...didFinishPickingMediaWithInfo()");
}
}
else
{
NSLog(@"Processing soon to saved photos album...else loop of lastPathComponent..didFinishPickingMediaWithInfo()");
}
}
[self dismissModalViewControllerAnimated:YES];
}
- (void)copyTempVideoToMediaLibrary :(NSString *)videoURL {
dispatch_queue_t mainQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(mainQueue, ^{
ALAssetsLibrary *library = [[[ALAssetsLibrary alloc] init] autorelease];
ALAssetsLibraryWriteVideoCompletionBlock completionBlock = ^(NSURL *assetURL, NSError *error) {
NSLog(@"Saved URL: %@", assetURL);
NSLog(@"Error: %@", error);
if (assetURL != nil) {
AVURLAsset *theAsset = [AVURLAsset URLAssetWithURL:[NSURL URLWithString:videoURL] options:nil];
NSArray *compatiblePresets = [AVAssetExportSession exportPresetsCompatibleWithAsset:theAsset];
AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:theAsset presetName:AVAssetExportPresetLowQuality];
[exportSession setOutputURL:[NSURL URLWithString:videoURL]];
[exportSession setOutputFileType:AVFileTypeQuickTimeMovie];
[exportSession exportAsynchronouslyWithCompletionHandler:^ {
switch ([exportSession status]) {
case AVAssetExportSessionStatusFailed:
NSLog(@"Export session faied with error: %@", [exportSession error]);
break;
default:
//[self mediaIsReady];
break;
}
}];
}
};
[library writeVideoAtPathToSavedPhotosAlbum:[NSURL URLWithString:videoURL] completionBlock:completionBlock];
});
}
Ответы
Ответ 1
Если вы хотите сжать видео для удаленного доступа и сохранить исходное качество для локального хранилища на iPhone, вы должны изучить AVAssetExportSession или AVAssetWriter.
Также ознакомьтесь с тем, как iOS управляет Assets.
- (void)convertVideoToLowQuailtyWithInputURL:(NSURL*)inputURL
outputURL:(NSURL*)outputURL
handler:(void (^)(AVAssetExportSession*))handler
{
[[NSFileManager defaultManager] removeItemAtURL:outputURL error:nil];
AVURLAsset *asset = [AVURLAsset URLAssetWithURL:inputURL options:nil];
AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:asset presetName:AVAssetExportPresetLowQuality];
exportSession.outputURL = outputURL;
exportSession.outputFileType = AVFileTypeQuickTimeMovie;
[exportSession exportAsynchronouslyWithCompletionHandler:^(void)
{
handler(exportSession);
[exportSession release];
}];
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
NSURL *videoURL = [info objectForKey:UIImagePickerControllerMediaURL];
NSURL *outputURL = [NSURL fileURLWithPath:@"/Users/josh/Desktop/output.mov"];
[self convertVideoToLowQuailtyWithInputURL:videoURL outputURL:outputURL handler:^(AVAssetExportSession *exportSession)
{
if (exportSession.status == AVAssetExportSessionStatusCompleted)
{
printf("completed\n");
}
else
{
printf("error\n");
}
}];
}
Ответ 2
Я думаю, что видео уже сжато кодеком h264. Но вы можете попытаться использовать AVFoundation для захвата видеофайлов с камеры. Но я подозреваю, что у вас будут те же размеры файлов.
Вот несколько статистических данных для 10-секундного видеофайла, записанного на iPhone 4, с различными качественными пресетами.
high (1280х720) = ~14MB = ~11Mbit/s
640 (640х480) = ~4MB = ~3.2Mbit/s
medium (360х480) = ~1MB = ~820Kbit/s
low (144х192) = ~208KB = ~170Kbit/s
Ответ 3
pickerController.videoQuality = UIImagePickerControllerQualityTypeMedium;
Это все значения, которые вы можете выбрать.
UIImagePickerControllerQualityTypeHigh = 0,
UIImagePickerControllerQualityType640x480 = 3,
UIImagePickerControllerQualityTypeMedium = 1, // default value
UIImagePickerControllerQualityTypeLow = 2
Ответ 4
Программное сжатие видео с помощью быстрого
И не забывайте добавлять - импортировать AssetsLibrary
func convertVideoWithMediumQuality(inputURL : NSURL){
let VideoFilePath = NSURL(fileURLWithPath: NSTemporaryDirectory()).URLByAppendingPathComponent("mergeVideo\(arc4random()%1000)d").URLByAppendingPathExtension("mp4").absoluteString
if NSFileManager.defaultManager().fileExistsAtPath(VideoFilePath) {
do {
try NSFileManager.defaultManager().removeItemAtPath(VideoFilePath)
} catch { }
}
let savePathUrl = NSURL(string: VideoFilePath)!
let sourceAsset = AVURLAsset(URL: inputURL, options: nil)
let assetExport: AVAssetExportSession = AVAssetExportSession(asset: sourceAsset, presetName: AVAssetExportPresetMediumQuality)!
assetExport.outputFileType = AVFileTypeQuickTimeMovie
assetExport.outputURL = savePathUrl
assetExport.exportAsynchronouslyWithCompletionHandler { () -> Void in
switch assetExport.status {
case AVAssetExportSessionStatus.Completed:
dispatch_async(dispatch_get_main_queue(), {
do {
let videoData = try NSData(contentsOfURL: savePathUrl, options: NSDataReadingOptions())
print("MB - \(videoData.length / (1024 * 1024))")
} catch {
print(error)
}
})
case AVAssetExportSessionStatus.Failed:
self.hideActivityIndicator(self.view)
print("failed \(assetExport.error)")
case AVAssetExportSessionStatus.Cancelled:
self.hideActivityIndicator(self.view)
print("cancelled \(assetExport.error)")
default:
self.hideActivityIndicator(self.view)
print("complete")
}
}
}
Ответ 5
Попробуйте несколько строк:
[[NSFileManager defaultManager] removeItemAtURL:outputURL error:nil];
AVURLAsset *urlAsset = [AVURLAsset URLAssetWithURL:inputURL options:nil];
AVAssetExportSession *session = [[AVAssetExportSession alloc] initWithAsset: urlAsset presetName:AVAssetExportPresetLowQuality];
session.outputURL = outputURL;
session.outputFileType = AVFileTypeQuickTimeMovie;
[session exportAsynchronouslyWithCompletionHandler:^(void)
{
handler(session);
}];
Ответ 6
Я нашел отличный пользовательский класс (SDAVAssetExportSession), чтобы выполнить сжатие видео. Вы можете скачать его из .
После загрузки в проект добавить файлы SDAVAssetExportSession.h и SDAVAssetExportSession.m, тогда приведенный ниже код поможет выполнить сжатие. В приведенном ниже коде вы можете сжать видео, указав разрешение и битрейт
#import "SDAVAssetExportSession.h"
- (void)compressVideoWithInputVideoUrl:(NSURL *) inputVideoUrl
{
/* Create Output File Url */
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *finalVideoURLString = [documentsDirectory stringByAppendingPathComponent:@"compressedVideo.mp4"];
NSURL *outputVideoUrl = ([[NSURL URLWithString:finalVideoURLString] isFileURL] == 1)?([NSURL URLWithString:finalVideoURLString]):([NSURL fileURLWithPath:finalVideoURLString]); // Url Should be a file Url, so here we check and convert it into a file Url
SDAVAssetExportSession *compressionEncoder = [SDAVAssetExportSession.alloc initWithAsset:[AVAsset assetWithURL:inputVideoUrl]]; // provide inputVideo Url Here
compressionEncoder.outputFileType = AVFileTypeMPEG4;
compressionEncoder.outputURL = outputVideoUrl; //Provide output video Url here
compressionEncoder.videoSettings = @
{
AVVideoCodecKey: AVVideoCodecH264,
AVVideoWidthKey: @800, //Set your resolution width here
AVVideoHeightKey: @600, //set your resolution height here
AVVideoCompressionPropertiesKey: @
{
AVVideoAverageBitRateKey: @45000, // Give your bitrate here for lower size give low values
AVVideoProfileLevelKey: AVVideoProfileLevelH264High40,
},
};
compressionEncoder.audioSettings = @
{
AVFormatIDKey: @(kAudioFormatMPEG4AAC),
AVNumberOfChannelsKey: @2,
AVSampleRateKey: @44100,
AVEncoderBitRateKey: @128000,
};
[compressionEncoder exportAsynchronouslyWithCompletionHandler:^
{
if (compressionEncoder.status == AVAssetExportSessionStatusCompleted)
{
NSLog(@"Compression Export Completed Successfully");
}
else if (compressionEncoder.status == AVAssetExportSessionStatusCancelled)
{
NSLog(@"Compression Export Canceled");
}
else
{
NSLog(@"Compression Failed");
}
}];
}
Отменить сжатие Использовать ниже строки кода
[compressionEncoder cancelExport]; //Video compression cancel
Ответ 7
Я взломал это.
Используйте exportSession.fileLengthLimit = 1048576 * 10 //10 MB
10 МБ - это жестко закодированное число. Используйте в соответствии с вашим необходимым битрейтом.