我正在尝试尽可能快地找到从iPhone(iOS5)上传视频的最佳方式 - 如果可能的话实时。
我发现之前的问题和答案非常有用 streaming video FROM an iPhone
但它给我留下了几个悬而未决的问题。我没有足够的代表在这个问题上发表评论 - 我认为我的问题无论如何都超出了原始问题的范围。
所以:
使用AVCaptureSession / AVAssetWriter并将视频剪切成短片是快速移动(压缩)iPhone视频的最佳方式 - 几乎实时?
如果是这样,有人可以提供有关如何使用两个AVAssetWriters和后台队列的更多详细信息以避免丢失(正如用户Steve McFarlin在上面引用的问题中提到的那样)?我不清楚从一个AVAssetWriter到另一个AVAssetWriter的切换是如何工作的......
(严重)有没有一种简单的方法可以将切碎的视频文件追加到一个完整长度的视频中......或者至少可以像播放一个完整的视频一样播放它们?我需要将较小的文件合并为服务器和iPhone上的一个文件(用于预览)。
感谢您的帮助......
答案 0 :(得分:4)
嗯,你可以尝试在手机上进行缓冲,但这对我来说似乎适得其反,因为它的内存有限。我会尝试设置一个AVCaptureSession并使用AVCaptureVideoDataOutput,它将在一个单独的dispatch_queue线程上向你提供帧(如果设置它将把它们作为MPEG帧出售)。该线程可以将帧移交给异步套接字以进行传输,可能使用指示帧编号和视频格式的小标头。或者,您可以通过队列将数据传送到发送线程,这样可以监视等待传输的帧数。
在接收服务器上,你想要处理创建一个小缓冲区(比如说几秒钟),并且如果它们无序到达就进行帧重新排序。
最大的问题是检测带宽并知道何时降低质量,这样你最终就不会有积压的数据包等待外出。这是一个完全不同和复杂的话题:)如果编解码器,质量和视频大小......将直接决定实时传输帧所需的带宽,关键将在您的选择中。在某些模式下,AVVideoCodecH264在硬件中受支持,可能是实时编码的唯一现实选择。
我认为你不会为此找到一个现成的例子,因为它代表了很多工作才能正常工作。
答案 1 :(得分:0)
2)以下是我在不丢帧的情况下对文件进行分块的方法:
- (void) segmentRecording:(NSTimer*)timer {
AVAssetWriter *tempAssetWriter = self.assetWriter;
AVAssetWriterInput *tempAudioEncoder = self.audioEncoder;
AVAssetWriterInput *tempVideoEncoder = self.videoEncoder;
self.assetWriter = queuedAssetWriter;
self.audioEncoder = queuedAudioEncoder;
self.videoEncoder = queuedVideoEncoder;
//NSLog(@"Switching encoders");
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
[tempAudioEncoder markAsFinished];
[tempVideoEncoder markAsFinished];
if (tempAssetWriter.status == AVAssetWriterStatusWriting) {
if(![tempAssetWriter finishWriting]) {
[self showError:[tempAssetWriter error]];
}
}
if (self.readyToRecordAudio && self.readyToRecordVideo) {
NSError *error = nil;
self.queuedAssetWriter = [[AVAssetWriter alloc] initWithURL:[self newMovieURL] fileType:(NSString *)kUTTypeMPEG4 error:&error];
if (error) {
[self showError:error];
}
self.queuedVideoEncoder = [self setupVideoEncoderWithAssetWriter:self.queuedAssetWriter formatDescription:videoFormatDescription bitsPerSecond:videoBPS];
self.queuedAudioEncoder = [self setupAudioEncoderWithAssetWriter:self.queuedAssetWriter formatDescription:audioFormatDescription bitsPerSecond:audioBPS];
//NSLog(@"Encoder switch finished");
}
});
}
https://github.com/chrisballinger/FFmpeg-iOS-Encoder/blob/master/AVSegmentingAppleEncoder.m
3)这是一个连接服务器上文件的脚本
import glob
import os
run = os.system # convenience alias
files = glob.glob('*.mp4')
out_files = []
n = 0
for file in files:
out_file = "out-{0}.ts".format(n)
out_files.append(out_file)
full_command = "ffmpeg -i {0} -f mpegts -vcodec copy -acodec copy -vbsf h264_mp4toannexb {1}".format(file, out_file)
run(full_command)
n += 1
out_file_concat = ''
for out_file in out_files:
out_file_concat += ' {0} '.format(out_file)
cat_command = 'cat {0} > full.ts'.format(out_file_concat)
print cat_command
run(cat_command)
run("ffmpeg -i full.ts -f mp4 -vcodec copy -acodec copy -absf aac_adtstoasc full.mp4")
https://github.com/chrisballinger/FFmpeg-iOS-Encoder/blob/master/concat-mp4.py