我正在使用AVPlayer播放HLS流。当用户按下录制按钮时,我还需要录制这些流。我使用的方法是分别录制音频和视频,然后在结束时合并这些文件,以制作最终的视频。并且它成功地处理了远程mp4文件。
但现在对于HLS (.m3u8)文件,我可以使用AVAssetWriter录制视频,但在音频录制方面有问题。
我正在使用MTAudioProccessingTap处理原始音频数据并将其写入文件。我关注了this的文章。我能够录制远程mp4音频,但它不能与HLS流。最初,我无法使用AVAssetTrack *audioTrack = asset tracksWithMediaType:AVMediaTypeAudio从流中提取音频轨道;
但是我能够使用KVO来初始化MTAudioProcessingTap来提取audioTracks。
-(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,以检查跟踪是否更改。
这就是我初始化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回调"Prepare“和"Process”再也不会被调用了。
我正在通过KVO的audioTrack有问题吗?
现在,如果有人能帮助我,我将不胜感激。或者我是否在使用写方法来记录HLS流?
发布于 2015-10-09 20:37:44
我找到了解决方案,并在我的应用程序中使用它。我想早点把它贴出来,但是没有时间。
因此,要使用HLS,您应该对它们的确切含义有所了解。关于这一点,请在苹果网站上看到。HLS Apple
以下是我正在遵循的步骤。1.首先获取m3u8并进行解析。您可以使用这个有用的工具包M3U8Kit来解析它。使用这个工具包,你可以得到M3U8MediaPlaylist或M3U8MasterPlaylist(如果它是一个主播放列表),如果你得到了主播放列表,你也可以解析它来得到M3U8MediaPlaylist
(void) parseM3u8
{
NSString *plainString = [self.url m3u8PlanString];
BOOL isMasterPlaylist = [plainString isMasterPlaylist];
NSError *error;
NSURL *baseURL;
if(isMasterPlaylist)
{
M3U8MasterPlaylist *masterList = [[M3U8MasterPlaylist alloc] initWithContentOfURL:self.url error:&error];
self.masterPlaylist = masterList;
M3U8ExtXStreamInfList *xStreamInfList = masterList.xStreamList;
M3U8ExtXStreamInf *StreamInfo = [xStreamInfList extXStreamInfAtIndex:0];
NSString *URI = StreamInfo.URI;
NSRange range = [URI rangeOfString:@"dailymotion.com"];
NSString *baseURLString = [URI substringToIndex:(range.location+range.length)];
baseURL = [NSURL URLWithString:baseURLString];
plainString = [[NSURL URLWithString:URI] m3u8PlanString];
}
M3U8MediaPlaylist *mediaPlaylist = [[M3U8MediaPlaylist alloc] initWithContent:plainString baseURL:baseURL];
self.mediaPlaylist = mediaPlaylist;
M3U8SegmentInfoList *segmentInfoList = mediaPlaylist.segmentList;
NSMutableArray *segmentUrls = [[NSMutableArray alloc] init];
for (int i = 0; i < segmentInfoList.count; i++)
{
M3U8SegmentInfo *segmentInfo = [segmentInfoList segmentInfoAtIndex:i];
NSString *segmentURI = segmentInfo.URI;
NSURL *mediaURL = [baseURL URLByAppendingPathComponent:segmentURI];
[segmentUrls addObject:mediaURL];
if(!self.segmentDuration)
self.segmentDuration = segmentInfo.duration;
}
self.segmentFilesURLs = segmentUrls;
}您可以看到,您将从m3u8解析它获得指向.ts文件的链接。
来做到这一点
然后,您可以删除.ts文件或保留它们,如果您需要它们。
发布于 2015-08-06 16:20:11
这不是一个好的方法,你可以做的就是解析M3U8链接,尝试下载段文件(.ts)。如果你能得到这些文件,你可以合并它们来生成mp4文件。
https://stackoverflow.com/questions/31700091
复制相似问题