【发布时间】:2015-10-20 09:54:32
【问题描述】:
我正在使用 AVPlayer 播放 HLS 流。而且我还需要在用户按下记录按钮时记录这些流。 我使用的方法是分别录制音频和视频,然后最后合并这些文件以制作最终视频。并且远程 mp4 文件是成功的。
但现在对于 HLS (.m3u8) 文件,我可以使用 AVAssetWriter 录制视频,但在录制音频时遇到问题。
我正在使用 MTAudioProccessingTap 处理原始音频数据并将其写入文件。我关注了this 文章。我能够录制远程 mp4 音频,但它不适用于 HLS 流。 最初,我无法使用 AVAssetTrack *audioTrack = [asset trackingWithMediaType:AVMediaTypeAudio][0] 从流中提取音轨;
但我能够使用 KVO 提取音频轨道来初始化 MTAudioProcessingTap。
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
AVPlayer *player = (AVPlayer*) object;
if (player.status == AVPlayerStatusReadyToPlay)
{
NSLog(@"Ready to play");
self.previousAudioTrackID = 0;
__weak typeof (self) weakself = self;
timeObserverForTrack = [player addPeriodicTimeObserverForInterval:CMTimeMakeWithSeconds(1, 100) queue:nil usingBlock:^(CMTime time)
{
@try {
for(AVPlayerItemTrack* track in [weakself.avPlayer.currentItem tracks]) {
if([track.assetTrack.mediaType isEqualToString:AVMediaTypeAudio])
weakself.currentAudioPlayerItemTrack = track;
}
AVAssetTrack* audioAssetTrack = weakself.currentAudioPlayerItemTrack.assetTrack;
weakself.currentAudioTrackID = audioAssetTrack.trackID;
if(weakself.previousAudioTrackID != weakself.currentAudioTrackID) {
NSLog(@":::::::::::::::::::::::::: Audio track changed : %d",weakself.currentAudioTrackID);
weakself.previousAudioTrackID = weakself.currentAudioTrackID;
weakself.audioTrack = audioAssetTrack;
/// Use this audio track to initialize MTAudioProcessingTap
}
}
@catch (NSException *exception) {
NSLog(@"Exception Trap ::::: Audio tracks not found!");
}
}];
}
}
我还在跟踪 trackID 以检查 track 是否已更改。
这就是我初始化 MTAudioProcessingTap 的方式。
-(void)beginRecordingAudioFromTrack:(AVAssetTrack *)audioTrack{
// Configure an MTAudioProcessingTap to handle things.
MTAudioProcessingTapRef tap;
MTAudioProcessingTapCallbacks callbacks;
callbacks.version = kMTAudioProcessingTapCallbacksVersion_0;
callbacks.clientInfo = (__bridge void *)(self);
callbacks.init = init;
callbacks.prepare = prepare;
callbacks.process = process;
callbacks.unprepare = unprepare;
callbacks.finalize = finalize;
OSStatus err = MTAudioProcessingTapCreate(
kCFAllocatorDefault,
&callbacks,
kMTAudioProcessingTapCreationFlag_PostEffects,
&tap
);
if(err) {
NSLog(@"Unable to create the Audio Processing Tap %d", (int)err);
NSError *error = [NSError errorWithDomain:NSOSStatusErrorDomain
code:err
userInfo:nil];
NSLog(@"Error: %@", [error description]);;
return;
}
// Create an AudioMix and assign it to our currently playing "item", which
// is just the stream itself.
AVMutableAudioMix *audioMix = [AVMutableAudioMix audioMix];
AVMutableAudioMixInputParameters *inputParams = [AVMutableAudioMixInputParameters
audioMixInputParametersWithTrack:audioTrack];
inputParams.audioTapProcessor = tap;
audioMix.inputParameters = @[inputParams];
_audioPlayer.currentItem.audioMix = audioMix;
}
但是现在有了这个音轨 MTAudioProcessingTap 回调“准备”和“处理”永远不会被调用。
我通过 KVO 获得的 audioTrack 有问题吗?
如果有人能帮我解决这个问题,我将不胜感激。或者可以告诉我是否使用写入方法来记录 HLS 流?
【问题讨论】:
-
你使用m3u8文件创建mp4文件成功了吗?
-
@Milan 我已经发布了答案。请检查。
-
你能分享一个录制直播的代码吗
标签: ios recording http-live-streaming m3u8