从AVPlayer获取HLS的PCM数据

2024-02-12

这个问题在过去几年里似乎被问过几次,但没有人回答。我正在尝试处理来自 HLS 的 PCM 数据,并且必须使用 AVPlayer。

这篇文章利用了本地文件https://chritto.wordpress.com/2013/01/07/processing-avplayers-audio-with-mtaudioprocessingtap/ https://chritto.wordpress.com/2013/01/07/processing-avplayers-audio-with-mtaudioprocessingtap/

此水龙头适用于远程文件,但不适用于 .m3u8 hls 文件。http://venodesigns.net/2014/01/08/recording-live-audio-streams-on-ios/ http://venodesigns.net/2014/01/08/recording-live-audio-streams-on-ios/

我可以播放播放列表中的前两首曲目,但它不会启动获取 pcm 所需的回调,当文件是本地或远程(不是流)时,我仍然可以获得 pcm,但 hls 不起作用,我需要 HLS 工作

这是我的代码

//avplayer tap try
- (void)viewDidLoad {
    [super viewDidLoad];

    NSURL*testUrl= [NSURL URLWithString:@"http://playlists.ihrhls.com/c5/1469/playlist.m3u8"];

    AVPlayerItem *item = [AVPlayerItem playerItemWithURL:testUrl];
    self.player = [AVPlayer playerWithPlayerItem:item];

    // Watch the status property - when this is good to go, we can access the
    // underlying AVAssetTrack we need.
    [item addObserver:self forKeyPath:@"status" options:0 context:nil];

}

-(void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context
{
    if(![keyPath isEqualToString:@"status"])
        return;

    AVPlayerItem *item = (AVPlayerItem *)object;
    if(item.status != AVPlayerItemStatusReadyToPlay)
        return;

    NSArray *tracks = [self.player.currentItem tracks];
    for(AVPlayerItemTrack *track in tracks) {
        if([track.assetTrack.mediaType isEqualToString:AVMediaTypeAudio]) {
            NSLog(@"GOT DAT FUCKER");
            [self beginRecordingAudioFromTrack:track.assetTrack];
            [self.player play];
        }
    }
}

- (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);
        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];
    self.player.currentItem.audioMix = audioMix;
}

void process(MTAudioProcessingTapRef tap, CMItemCount numberFrames,
             MTAudioProcessingTapFlags flags, AudioBufferList *bufferListInOut,
             CMItemCount *numberFramesOut, MTAudioProcessingTapFlags *flagsOut)
{
    OSStatus err = MTAudioProcessingTapGetSourceAudio(tap, numberFrames, bufferListInOut,
                                                      flagsOut, NULL, numberFramesOut);
    if (err) NSLog(@"Error from GetSourceAudio: %d", (int)err);

    NSLog(@"Process");

}

void init(MTAudioProcessingTapRef tap, void *clientInfo, void **tapStorageOut)
{
    NSLog(@"Initialising the Audio Tap Processor");
    *tapStorageOut = clientInfo;
}

void finalize(MTAudioProcessingTapRef tap)
{
    NSLog(@"Finalizing the Audio Tap Processor");
}

void prepare(MTAudioProcessingTapRef tap, CMItemCount maxFrames, const AudioStreamBasicDescription *processingFormat)
{
    NSLog(@"Preparing the Audio Tap Processor");
}

void unprepare(MTAudioProcessingTapRef tap)
{
    NSLog(@"Unpreparing the Audio Tap Processor");
}

void init叫做void prepare and process也必须被调用。

我怎样才能做到这一点?


我建议您使用 FFMPEG 库来处理 HLS 流。这有点困难,但提供了更大的灵活性。几年前我做了 Android 版 HLS Player(使用了这个项目 https://github.com/appunite/AndroidFFmpeg)我相信同样适用于 iOS。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

从AVPlayer获取HLS的PCM数据 的相关文章

  • 使用 iPhone 摄像头检测心率 [重复]

    这个问题在这里已经有答案了 可能的重复 使用摄像头检测心率 https stackoverflow com questions 9274027 detecting heart rate using the camera 我正在研究 iOS
  • “同时创建 xib 文件”按钮已禁用

    我在创建时遇到这个问题UIView s子类 创建 例如 UIViewControllers or UITableViewCells没关系 为什么会出现这种情况 I create view using cmd N and Xcode Vers
  • 在我的Android中,当其他应用程序想要录制音频时如何停止录音?

    在我的应用程序中 服务通过 AudioRecord 持续录制音频 当我的应用程序运行时 其他与音频记录相关的应用程序 例如 Google 搜索 无法工作 如何知道何时有其他应用想要录制音频 以便我可以停止录制以释放资源 答案是MediaRe
  • 尝试复制文件时出错

    我正在尝试使用 NSFileManager 将临时文件复制到另一个位置 但是它失败并抱怨其中一个文件不存在 Copy temp file NSError error BOOL exists fileManager fileExistsAtP
  • iOS 10 的错误? NSDate 日本地区时间描述和 24 小时休息

    这似乎是 iOS 10 的一个错误 在 iOS 8 和 9 中都可以 NSDate date description 的小时描述是错误的 它附加了 24 小时描述和 12 小时描述 我没有使用 NSDateFormatter 只是默认设置
  • 由于语言错误,Itunes Connect 无法提交

    Thats all it shows https i stack imgur com 0aZm8 png 我不确定它没有告诉我出了什么问题 it shows its linked to the language https i stack
  • Swift - 选择值后隐藏 pickerView

    我发现了类似的问题 他们的答案很有帮助 但我坚持最后一件事 我试图在点击字段时显示 pickerView 然后选择数据时 我希望 pickerView 隐藏 我可以从 pickerView 获取数据来隐藏 但是 pickerView 后面仍
  • iOS 11 安全区域布局指南向后兼容性

    启用安全区域布局指南是否与 iOS 11 以下版本兼容 我设法使用新的安全区域布局指南并保持与 iOS 9 和 iOS 10 的向后兼容性 编辑 正如 NickEntin 的评论所指出的 此实现将假定存在状态栏 但在 iPhone X 的横
  • 如何检测Retina高清显示屏?

    UIScreen有一个新的 nativeScaleiOS 8 中的属性 但文档没有提及它 property nonatomic readonly CGFloat nativeScale 还有一个scale属性 但文档说它是 2 用于视网膜显
  • PresentModalViewController 不执行任何操作

    我有一个 UIViewController parent 调用presentModalViewController与另一个 UIViewController child on viewDidLoad If parent没有 UINaviga
  • 在后台任务中安排通知

    我正在为 iOS 开发一个日历 闹钟应用程序 它与网络服务器同步 当在服务器上添加活动时 会发出推送通知 以便 iOS 客户端可以获取新数据 并根据需要更新和安排下一次警报的时间 本地通知 但这仅在应用程序在客户端打开时才有效 我希望客户端
  • UISearchController 保留问题

    我正在尝试使用 UISearchController 但是我遇到了无法解决的保留问题 MainTableview 有两个部分 第1节 基于某些正则表达式过滤数据 第2节 All Data 我将 UISearchController 添加到我
  • 在 Swift 中自动移动 UISlider

    我想在按下按钮时将 UISlider 从 minValue 循环移动到 maxValue 并在再次按下按钮时将其停止在当前位置 我想使用 Swift 我遇到的主要问题是函数 slider setValue 太快了 我希望动画更慢 IBAct
  • 线程 1:信号 SIGABRT - AppDelegate.h

    main m Journey Created by Julian Buscema on 2014 07 13 Copyright c 2014 Julian Buscema All rights reserved import
  • Objective C UIImagePNGRepresentation内存问题(使用ARC)

    我有一个基于 ARC 的应用程序 它从 Web 服务加载大约 2 000 个相当大 1 4MB 的 Base64 编码图像 它将 Base64 解码后的字符串转换为 png图像文件并将其保存到磁盘 这一切都是在一个循环中完成的 我不应该有任
  • 我可以知道 requireGestureRecognizerToFail 到底会做什么吗?

    谁能告诉我下面的代码行到底会做什么 我已经提到过Apples https developer apple com library ios documentation uikit reference UIGestureRecognizer C
  • 使用 UIImageJPEGRepresentation 时,compressionQuality 应该是多少?

    我想对用户库中的照片应用滤镜 然后将其写回磁盘 我在用着UIImageJPEGRepresentation 该函数需要一个UIImage and a compressionQuality值介于 0 0 和 1 0 之间 因为我想保留原始质量
  • iOS7 中“-webkit-overflow-scrolling: touch” 最初的屏幕外元素被破坏

    既然转基因种子已经发布了 我们现在可以谈谈了 看起来 iOS7 中的 webkit overflow scrolling touch 已损坏 最初不在屏幕上的元素的触摸事件不会触发 或者在某些情况下只是不可靠 这是一个例子
  • 在 UIMenuItem 上设置accessibilityLabel

    我正在尝试设置accessibilityLabel of a UIMenuItem而且似乎没有效果 无论如何 VoiceOver 只是读取项目的标题 let foo UIMenuItem title foo action selector
  • KeyboardAvoidingView - 隐藏键盘时重置高度

    我正在使用 React NativeKeyboardAvoidingView设置我的高度View当显示键盘时 但是当我关闭应用程序中的键盘时 视图的高度不会变回原来的值

随机推荐

  • ConcurrentHashmap 同时进行写入和获取操作

    我有一个关于 ConcurrentHashMap 的问题 假设我有 2 个线程 线程 A 尝试从共享 ConcurrentHashMap 中获取对象 线程B清除共享映射 如果线程 A 和线程 B 同时访问共享资源 会发生什么情况 我搜索了文
  • 从按下的按钮获取文本

    如何从按下的按钮获取文本 安卓 我可以从按钮获取文本 String buttonText button getText 我可以从按下的按钮获取 id int buttinID view getId 目前我不知道如何获取按下的按钮上的文本 p
  • 规划网络应用程序

    我即将开始建立新的初创公司 因此我需要您的一些指导 规划网站的最佳方法是什么 我不认为 首先设计 然后数据库关系 然后开始开发 而是 如何规划应用程序的工作方式 是否有一些经过验证的方法 例如制作网站 蓝图 的最佳方法 例如使用某种工具或其
  • Docker php:fpm—安装 php 扩展

    我用的是官方的php fpmdocker 镜像作为我的应用程序容器的基础 所以Dockerfile像这样开始 FROM php fpm 稍后在文件中我希望有类似的内容 RUN apt get install y php7 0 gd 但这告诉
  • 连续分数

    我对连续分数的理解是它总是以分数形式表示小数 我认为连续分数总是返回小于或等于小数的值 不幸的是 我的代码有时会返回大于十进制输入的小数值 我对连续分数的理解正确吗 如果是这样 请解释一下我的代码中的错误所在 public static R
  • JavaScript 获取样式

    是否可以使用 JavaScript 获取对象的所有样式 就像是 main css myLayer position absolute width 200px height 100px color 0000ff main js var ob
  • 在 ASP.NET MVC 5 中从 Facebook v2.4 API 访问 OAuthExternalLoginCallback 中的电子邮件地址[重复]

    这个问题在这里已经有答案了 对于 Facebook API v2 3 如果设置了以下内容 用户的电子邮件地址将在回调中返回ExternalLoginCallback app UseFacebookAuthentication new Fac
  • Apache Tomcat 8 不工作。抛出 HTTP 状态 500 - java.lang.ClassNotFoundException: org.apache.jsp.index_jsp

    我正在使用 Apache Tomcat 8 和 JDK 1 7 运行 startup bat 后 Tomcat 开始运行 但当我尝试跑步时 http localhost 8080 它显示一个错误 HTTP 状态 500 java lang
  • 提交到 Web 服务器的希伯来语字符串未收到希伯来语版本

    我从我的应用程序向网络服务器提交注册表单 EditText email EditText findViewById R id email EditText password EditText findViewById R id passwo
  • 使用 cin 检查空行

    我想检查是否有空行作为输入来执行特定操作 我尝试使用 cin peek 并检查它是否等于 n 但它没有意义 a b c 空行 在这里 我想执行我的操作 a 我试过这段代码 char a b c cin gt gt a cin gt gt b
  • MS Access 中的一对一关系

    我在 MS Access 中的两个表之间创建一对一关系时遇到问题 当我创建关系时 它默认为 多对一 并且我没有看到更改它的选项 有没有办法做到这一点 Access没有这样的概念 您可以将两个表合并为一个表 也可以在两个表上为公共字段放置唯一
  • Tomcat 访问日志中的 HTTP 状态代码 500 ClientAbortException / 管道损坏

    我们使用 Kibana 设置了一些仪表板和可视化 以监控 tomcat 为 Spring Boot Web 应用程序生成的访问日志 我们特别关注状态代码为 5xx 的请求 事实证明 如果客户端请求资源 并且在请求正在进行时取消该请求 使用C
  • 在 vb.net 中关闭数据读取器的正确点

    我在 vb net 中有这段代码 reader myCommand ExecuteReader If reader HasRows Then While reader read End While End If 我应该在之后使用 reade
  • 闪亮:动态更改选项卡名称

    我正在开发一个应该处理多种语言的闪亮应用程序 我设法动态翻译应用程序的几乎所有元素 具体取决于selectInput选择语言 然而 困难的事情 仍然是navbarPage选项卡以及tabPanels在我的页面内 我不能改变他们的名字 我尝试
  • 美丽的汤和表抓取 - lxml 与 html 解析器

    我正在尝试使用 BeautifulSoup 从网页中提取表格的 HTML 代码 table class facts label table 我想知道为什么下面的代码适用于 html parser 并打印回来none如果我改变 html pa
  • 什么是顶点数组对象?

    我今天刚刚开始从本教程学习 OpenGL http openglbook com the book http openglbook com the book 我读到了第二章 画了一个三角形 除了 VAO 这个缩写可以吗 之外 我理解了所有内
  • iOS 7/8 UITableView Cell:两个具有动态高度的 UILabel,具有可变行高的自动布局

    因此 当我只有一个标签可以根据字符串的长度更改高度时 我可以使用自动布局设置动态高度大小 我的问题是 如果我添加另一个应该执行相同操作的 UILabel 事情就不会成功 我将内容拥抱优先级和压缩阻力都设置为 1000 我收到歧义警告 如果我
  • INNER JOIN 独特 ID

    我有以下代码 FROM CTE Order cte INNER JOIN tblOrders o ON cte OrderId o Id INNER JOIN tblOrderUnits ou ON o id ou OrderId INNE
  • javafx 中具有不同单元格值的 TableView

    在下面的代码中有 4 列 在 特定值 列中 可以添加不同类型的数据 如字符串 整数 日期等 但我想在同一列中在该单元格中输入的值旁边添加一个按钮 前提是该值是字符串 像这样的东西 名字 姓氏 年龄 特别价值 詹姆斯 史密斯 10 10 10
  • 从AVPlayer获取HLS的PCM数据

    这个问题在过去几年里似乎被问过几次 但没有人回答 我正在尝试处理来自 HLS 的 PCM 数据 并且必须使用 AVPlayer 这篇文章利用了本地文件https chritto wordpress com 2013 01 07 proces