Весьма интересный вопрос. Вот что я придумал:
Насколько я знаю, вы не можете напрямую сохранить видеопоток, играя с вашего MPMoviePlayerController
, но вы можете сохранить данные , как ваше видео в потоковом режиме с помощью dataWithContentsOfURL:
. Затем, как только данные будут сохранены успешно, вы можете разделить его на видео и/или аудиокомпоненты, например:
- (void)saveFullVideo {
// Create a temporary file path to hold the
// complete version of the video
NSURL *tmpDirURL = [NSURL fileURLWithPath:NSTemporaryDirectory() isDirectory:YES];
NSURL *fileURL = [[tmpDirURL URLByAppendingPathComponent:@"temp"]
URLByAppendingPathExtension:@"mov"]; // <-- assuming the streaming video's a .mov file
NSError *error = nil;
NSData *urlData = [NSData dataWithContentsOfURL:streamingURL];
[urlData writeToURL:fileURL options:NSAtomicWrite error:&error];
// If the data is written to the temporary file path
// successfully, split it into video and audio components
if (!error) {
[self saveVideoComponent:fileURL];
[self saveAudioComponent:fileURL];
}
}
- (void)saveVideoComponent:(NSURL*)videoUrl {
AVURLAsset* videoAsset = [[AVURLAsset alloc]initWithURL:videoUrl options:nil];
AVMutableComposition *composition = [AVMutableComposition composition];
// Create a mutable track of type video
AVMutableCompositionTrack *videoCompositionTrack = [composition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
NSError *error = nil;
// Get the video portion of the track and insert it
// into the mutable video composition track
AVAssetTrack *video = [[videoAsset tracksWithMediaType:AVMediaTypeVideo] firstObject];
[videoCompositionTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, videoAsset.duration) ofTrack:video atTime:kCMTimeZero error:&error];
// Create a session to export this composition
AVAssetExportSession* assetExport = [[AVAssetExportSession alloc] initWithAsset:composition presetName:AVAssetExportPresetPassthrough];
// Create the path to which you'll export the video
NSString *docPath = [NSSearchPathForDirectoriesInDomains
(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *exportPath = [docPath stringByAppendingPathComponent:@"/video_path.mp4"];
NSURL *exportUrl = [NSURL fileURLWithPath:exportPath];
// Remove the old file at the export path if one exists
if ([[NSFileManager defaultManager] fileExistsAtPath:exportPath])
{
[[NSFileManager defaultManager] removeItemAtPath:exportPath error:nil];
}
assetExport.outputFileType = AVFileTypeMPEG4;
assetExport.outputURL = exportUrl;
assetExport.shouldOptimizeForNetworkUse = YES;
[assetExport exportAsynchronouslyWithCompletionHandler:
^(void)
{
switch (assetExport.status)
{
case AVAssetExportSessionStatusCompleted: {
NSLog(@"Video export Saved to path: %@", exportUrl);
break;
} case AVAssetExportSessionStatusFailed: {
NSLog(@"Export Failed");
NSLog(@"ExportSessionError: %@", [assetExport.error localizedDescription]);
break;
} case AVAssetExportSessionStatusCancelled: {
NSLog(@"Export Cancelled");
NSLog(@"ExportSessionError: %@", [assetExport.error localizedDescription]);
break;
} default: {
NSLog(@"Export Default condition");
}
}
}];
}
- (void)saveAudioComponent:(NSURL*)videoUrl {
AVURLAsset* videoAsset = [[AVURLAsset alloc]initWithURL:videoUrl options:nil];
AVMutableComposition *composition = [AVMutableComposition composition];
// Create a mutable track of type audio
AVMutableCompositionTrack *audioCompositionTrack = [composition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
NSError *error = nil;
// Get the audio portion of the track and insert it
// into the mutable audio composition track
AVAssetTrack *audio = [[videoAsset tracksWithMediaType:AVMediaTypeAudio] firstObject];
[audioCompositionTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, videoAsset.duration) ofTrack:audio atTime:kCMTimeZero error:&error];
// Create a session to export this composition
AVAssetExportSession* assetExport = [[AVAssetExportSession alloc] initWithAsset:composition presetName:AVAssetExportPresetPassthrough];
// Create the path to which you'll export the audio
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *dataPath = [documentsDirectory stringByAppendingPathComponent:@"VideoFolder"];
// Create folder if needed
[[NSFileManager defaultManager] createDirectoryAtPath:dataPath withIntermediateDirectories:YES attributes:nil error:nil];
NSString *exportPath = [dataPath stringByAppendingPathComponent:@"audio_path.caf"];
NSURL *exportUrl = [NSURL fileURLWithPath:exportPath];
// Remove the old file at the export path if one exists
if ([[NSFileManager defaultManager] fileExistsAtPath:exportPath])
{
[[NSFileManager defaultManager] removeItemAtPath:exportPath error:nil];
}
assetExport.outputFileType = AVFileTypeCoreAudioFormat;
assetExport.outputURL = exportUrl;
assetExport.shouldOptimizeForNetworkUse = YES;
[assetExport exportAsynchronouslyWithCompletionHandler:
^(void)
{
switch (assetExport.status)
{
case AVAssetExportSessionStatusCompleted: {
NSLog(@"Audio export Saved to path: %@", exportUrl);
//[self playAudio:exportUrl];
break;
} case AVAssetExportSessionStatusFailed: {
NSLog(@"Export Failed");
NSLog(@"ExportSessionError: %@", [assetExport.error localizedDescription]);
break;
} case AVAssetExportSessionStatusCancelled: {
NSLog(@"Export Cancelled");
NSLog(@"ExportSessionError: %@", [assetExport.error localizedDescription]);
break;
} default: {
NSLog(@"Export Default condition");
}
}
}];
}
Спасибо за ответ Lyndsey! Я собираюсь попробовать и вернуться к вам. – technophyle
Спасибо за ваш ответ Линдси. Решение, похоже, работает. У меня есть другой вопрос. Если мне нужно сделать это задание на часть видео (например, когда пользователь нажимает кнопку «Начать запись» и «Остановить запись») во время воспроизведения (потоковой передачи) видео, как вы это сделаете? Считаете ли вы это возможным? – technophyle
@technophyle Вы должны иметь возможность изменять все экземпляры CMTimeRangeMake в любом диапазоне, в котором вы нуждаетесь –