使用Wowza GoCoder SDK for iOS构建直播应用程序的经验

构建具有实时流功能的应用程序并非易事。 有许多动人的作品组成了这样的应用程序。 如果要构建自己的音频和视频编码器/解码器,则需要具备AVFoundationAudioToolboxVideoToolbox和其他工具的专业知识。 其中许多框架都是完整的黑匣子,尤其是VideoToolbox

有一些第三方选项可以为您带来所有的辛苦工作,但它们并不是它们所宣传的一切。 我们将看一下Wowza Media Systems的GoCoder SDK。 Wowza是实时流媒体解决方案的主要提供商。 我想提一下,我不是Wowza的会员,认可或赞助的人。 该SDK是专有的,不提供对其源代码的访问。

当我面对为客户端构建应用程序实时流传输部分的挑战时,我评估了一些解决问题的方法。 第一个是建造自己的编码器,但是截止日期不允许我按时完成任务。 他们还拥有由Wowza支持的所有服务器端基础架构,这是我们认为也适合将移动SDK用于该应用程序的原因之一。

文档资料

GoCoder随附了完整的API参考和一些示例应用程序,这些示例应用程序演示了SDK的某些功能。 他们在App Store中也有一个应用程序,您可以使用流服务器参数对其进行配置,并在几分钟内上线。 最初,这非常好,但是我很快发现这些示例几乎是“ Hello World”类型的应用程序,并且API引用除了列出类,属性和方法之外没有提供任何其他功能。 我一个人。

设置SDK

设置SDK非常简单:您只需将属性传递给配置对象,其中包含视频,音频和需要连接的流服务器实例的设置。 然后将其分配给GoCoder主类的共享实例,使用回调委托对象调用startStreaming方法,您会很startStreaming

挑战

在开发过程中,我发现实现GoCoder带来了一系列独特的挑战,不幸的是,编写SDK时甚至没有考虑到其开发人员。

提供可靠的移动实时流媒体体验并不容易。 有许多变量需要考虑,以下是您必须特别注意的变量:

  1. 性能和电池寿命
  2. 连接稳定性
  3. 打断
  4. 有线和无线耳机
  5. 后台执行
  6. 一般错误处理

如果您运行Wowza的示例或在App Store中使用其自己的应用程序,则仅在遵循以下令人满意的路径时才能进行实时流式传输体验:广播过程中无中断,无连接中断或带宽变化,无外部附件连接。

所有这些情况使我们发现该SDK远未经过考虑了我们团队所做的一切的质量检查团队的测试。 感谢我的质量检查团队在帮助我发现和解决SDK团队没有解决的许多问题方面所做的辛勤工作,我花了一点时间表示感谢。

关于性能

考虑到音频和视频编码对于硬件来说是繁重的任务,因此该SDK的性能很高并且可以节省电池。 我们在这方面面临的问题之一是,在启动和停止广播时,线程问题导致应用程序崩溃,甚至他们的示例和他们自己的应用程序也因此受到影响。 在提交带有其他问题的票证8个月后,我们足够“幸运”地解决了该特定问题,是的,截至本文撰写时,Wowza尚未解决。 请勿使用低于1.5.1.x的GoCoder任何版本,它们会在那里修复线程问题。

连接稳定性

移动实时流媒体非常容易受到网络状况和连接质量的影响。 GoCoder提供了基本的自适应比特率和帧频系统,该系统试图适应带宽的变化。 它并非一直都能正常工作。

如果您使用WiFi开始广播并切换到蜂窝网络,请准备好实施第一个解决方法:SDK不能很好地过渡,并且会引发错误。 您可以使用可达性侦听器来验证引发的错误确实是由连接丢失或更改引起的,然后重新启动广播。

一些流媒体架构会遭受此困扰,因为它们提供了同步广播功能,并且具有相同流名称的广播一旦结束就无法重新启动。 是的,我也很幸运。 如果广播在几秒钟内结束,我们的服务器端流媒体团队就不得不付出大量的额外工作来适应“恢复”广播的功能。 请牢记有关此恢复功能的知识,下一部分将对其进行很多提及。

打断

准备对此感到惊讶: 任何音频会话中断都将杀死广播音频,并且将永远无法恢复。 警报,提醒,Siri, 电话以及几乎任何会触发AVAudioSessionInterruption都会使您的音频完全消失。 SDK不会以任何方式在内部处理此问题。 当我提交包含该问题的票证时,答案是停止广播并在中断结束后重新开始播放。

任何具有AVFoundation基本知识的开发人员AVFoundation知道, began中断通知并不能保证也会收到ended通知。 到目前为止,我们很幸运,我们测试过的所有干扰都发送了。

基本上,您必须实现AVAudioSessionInterruptionNotification观察器,并相应地启动/停止广播。 希望您的流传输体系结构不必在服务器端实现“恢复”逻辑。

在所有中断中都必须考虑特殊情况: 电话 。 这些不能被视为常规的AVAudioSessionInterruption ,因此您必须使用CXCallObserver对象来实现停止/启动广播的逻辑。 这意味着您的应用程序不支持低于10.0 iOS版本。

有线和无线耳机

您会认为这些将立即可用吗? 好吧……不! 以任何组合方式连接和断开有线/无线耳机会杀死您的音频。 Wowza的解决方案再次是“停止并重新开始广播”。

为此,您需要实现自己的AVAudioSessionRouteChangeNotification观察器并相应地停止/开始广播。

值得一提的是,如果您没有使用.videoChat模式配置音频会话,请不要使用蓝牙耳机,因为它们根本无法与GoCoder一起正常工作 。 GoCoder音频引擎存在内部问题,该引擎基于AudioQueue服务而不是AudioGraph 。 这也是上述所有音频问题都存在的原因。

使用.videoChat模式时需要权衡:使用内置麦克风会导致广播音量低于预期,这是由于设备的音调均衡和自动增益控制起作用,一旦发生这种情况,您将无法设置手动输入增益。

为了解决这个问题,您需要使用AudioToolbox API(在C中),然后点击“ Voice Processing I/O单元。 在撰写本文时,我仍在这样做。 稍后我将对其进行更新,以阐明如何执行此操作。

后台执行

到目前为止,您已经是一名优秀的开发人员,并且实现了网络,音频中断和音频路由更改所需的所有处理程序。 GoCoder提供了一个属性,如果您在直播时将应用程序发送到后台,则可让您保持仅音频模式的广播。 这听起来很美妙,直到您在后台收到中断并且您的管理员尝试开始和停止广播为止。

当在后台调用GoCoder的startStreamingendStreaming方法时,它们会变成香蕉。 到这个时候,上述所有处理程序的代码看起来已经很恐怖了。 我认为这不值得,并且禁用了仅背景音频模式。 猜猜我做了什么? 触发UIApplicationDidEnterBackgroundUIApplicationDidBecomeActive通知时的开始/停止周期。

您还必须验证上述所有条件,以检查音频中断/路线更改以及与此相关的电话呼叫处理程序。 到处都是旗帜!!!

一般错误处理

当GoCoder引发错误时,您会期望一些错误代码和描述所发生情况的消息。 准备接收所有错误的完全相同的错误消息。 您是否错过了音频采样率或将其设为无效值? 您会收到与失去连接相同的错误消息。 我们不要忘记在其API参考或任何地方都有关于错误代码的ZERO文档。

您会对此有很多乐趣,相信我,我勉强睡了3至4个星期试图解决这些问题,并认为这是我的问题。 我内心深处知道不是我,但发现要消化所有这些发现并将其报告给质量保证和我的首席技术官真的很难。 我仍然很难相信,并且以某种形式,我现在对此感到害怕。 我在代码中花了所有可能的选项来尝试验证它不是我,而是它们。

我的要点和建议

绝不是GoCoder是iOS上的移动实时流媒体的银弹。 该框架需要进一步成熟,以进行更多的开发,测试和调试。 不要误会我的意思,当它起作用时,它会产生具有惊人质量和设备性能的美丽直播流。 必须承认这一点,这对Wowza团队来说是赞誉。 我只希望产品对我们的开发人员以及我们的最终用户不断改进。 GoCoder是专有解决方案,而且获得许可证并不便宜。 我最不希望的是高级支持,因为他们将其宣传为高级产品。 我们也为此付出了很多钱。

其他选择

没有什么比开源软件更好。 它是可靠的,受支持的,并且如果出现故障,您可以自己做出贡献并进行修复。 此外,对于正在发生的事情以及如何完成事情也具有透明度。 我最近一直在使用名为HaishinKit的开源实时流框架。 它看起来很有希望,并且开发人员友好且乐于解决GitHub上的问题。 这可能是一个更好的选择,但是再次,您需要对其进行彻底评估,以确定它是否是您的最佳选择。

让我帮忙分担痛苦

如果您或您的公司决定构建实时流应用程序,那么我想让您知道我是实施GoCoder / HaishinKit的专家。 我已经下地狱了,回来了,并且确切地知道该怎么做才能唱歌。 请随时与我联系以获取有关我的咨询服务的其他信息。