gpt4 book ai didi

ios - 在播放 iOS 时从 HLS 流(视频)中提取/录制音频

转载 作者:技术小花猫 更新时间:2023-10-29 11:03:27 25 4
gpt4 key购买 nike

我正在使用 AVPlayer 播放 HLS 流。而且我还需要在用户按下录制按钮时录制这些流。我使用的方法是分别录制音频和视频,然后在最后合并这些文件以制作最终视频。并且它对远程 mp4 文件是成功的。

但现在对于 HLS (.m3u8) 文件,我可以使用 AVAssetWriter 录制视频,但在录制音频时遇到问题。

我正在使用 MTAudioProccessingTap 处理原始音频数据并将其写入文件。我关注了this文章。我能够录制远程 mp4 音频,但它不适用于 HLS 流。最初我无法使用 AVAssetTrack *audioTrack = [asset tracksWithMediaType:AVMediaTypeAudio][0]; 从流中提取音轨。

但我能够使用 KVO 提取 audioTracks 来初始化 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 以检查轨道是否已更改。

这就是我初始化 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 流?

最佳答案

我找到了解决方案并在我的应用中使用它。想早点发但是没时间。

因此,要使用 HLS,您应该了解它们到底是什么。为此,请在 Apple 网站上查看。 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 文件的链接。

  1. 现在将所有 .ts 文件下载到本地文件夹中。
  2. 将这些 .ts 文件合并为一个 mp4 文件并导出。你可以使用这个很棒的 C 库来做到这一点 TS2MP4

然后您可以删除 .ts 文件或在需要时保留它们。

关于ios - 在播放 iOS 时从 HLS 流(视频)中提取/录制音频,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31700091/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com