在iPhone程序中使用后台音乐播放和VoIP
来源:互联网 发布:什么是虚拟机软件 编辑:程序博客网 时间:2024/06/04 08:28
原文: http://blog.toshsoft.de/index.php?/archives/4-Adding-Background-Audio-and-VoIP-to-your-iPhone-App.html
Oct 5. 2010
今天,我会贴出关于iOS 后台任务中的Audio和VoIP的问题,也许你也会遇到同我一样的问题。
本教程使用C库处理sockets,而没有使用苹果的高级API。如果你向用苹果的API,请阅读苹果文档这里
首先,你需要在Info.plist文件中添加新的键UIBackgroundModes,表示你的后台任务类型,包括这两个值:
audio
voip
此外你需要保证,当你从后台恢复时所有的UDP sockets必须被重新open,因为它们不再有效,你会收到SIGPIPE错误。处理SIGPIPE的方法不止一个,其中一个方法就是设置socket选项,让它忽略SIGPIPE。
- // Ignore SIGPIPE because you will get it sometimes after going into zhe
- int set = 1;
- setsockopt(m_bsdSocket, SOL_SOCKET, SO_NOSIGPIPE, (void *)&set, sizeof(set));
setsockopt应该在socket实例创建之后就调用。
你也可以用异常处理的办法简单地忽略SIGPIPE(Matt Gallagher 有一个很好的例子 这里)。在StackOverflow上也能找到大量的源代码。无论如何你都要进行处理。如果你尝试读取一个断开的socket,你会得到EPIPE、ECONNRESET或ENOTCONN错误。
现在进入正题。在进行tcp socket连接之后,我们将一个读取流关联上去,然后将它(流)设置为kCFStreamNetworkServiceTypeVoIP,以便iOS认为它应该在socket上监听。现在,socket会报告收到数据,哪怕App进入后台,电话仍然是被监听的。示例代码如下:
- #if defined(__IPHONE_4_0) && !(TARGET_IPHONE_SIMULATOR)
- // A read stream handle
- CFReadStreamRef hReadStream;
- // Only do this if it is a SipSocket we are watching
- if (IsSipSocket(bsdSocket))
- {
- // Set it to non-blocking
- int set = 1;
- ioctl(bsdSocket, FIONBIO, reinterpret_cast<int>(&set));
- CFStreamCreatePairWithSocket (kCFAllocatorDefault, bsdSocket,
- &hReadStream, NULL);
- if (CFReadStreamSetProperty(hReadStream,
- kCFStreamNetworkServiceType,
- kCFStreamNetworkServiceTypeVoIP) != TRUE)
- {
- // An error occured, delete the stream
- if(hReadStream != NULL)
- {
- CFReadStreamClose(hReadStream);
- CFRelease(hReadStream);
- hReadStream = NULL;
- }
- return -1;
- }
- if (CFReadStreamOpen(hReadStream) != TRUE)
- {
- // An error occured, delete the stream
- if(hReadStream != NULL)
- {
- CFReadStreamClose(hReadStream);
- CFRelease(hReadStream);
- hReadStream = NULL;
- }
- return -1;
- }
- }
- #endif
重启或关闭socket时,对应的读取流也应被关闭。
- #if defined(__IPHONE_4_0) && !(TARGET_IPHONE_SIMULATOR)
- if (hReadStream)
- {
- CFReadStreamClose(hReadStream);
- CFRelease(hReadStream);
- hReadStream = NULL;
- }
- #endif
这确实很简单,但我花了许多时间才抓住问题的关键。如往常一样,你可以随意使用和修改这些代码,但如果你觉得它们对你有用,或者发现错误,请留下你的意见。
- 在iPhone程序中使用后台音乐播放和VoIP
- 使用MediaPlayer在Service中后台播放网络音乐
- iphone 后台播放音乐问题
- iphone 后台循环播放音乐
- 在网页中使用mediaplayer和realplayer播放音乐
- 在控制台程序中播放音乐
- 程序中播放音乐
- 后台运行程序时 音乐继续播放
- 音乐播放器类程序后台运行
- Loading and Playing Audio in an Applet:在applet程序中加载和播放音乐
- iOS中实现音乐的后台播放
- 使用 AVAudioSession 实现后台播放音乐
- 使用AudioSession实现音乐后台播放功能
- 在MFC中播放音乐
- 在Service中播放音乐
- 在服务中播放音乐
- C++ 在多线程中使用mciSendString播放音乐 上篇
- C++ 在多线程中使用mciSendString播放音乐 下篇
- android自定义listview,添加监听器,解决屏幕滑动组件状态干扰的问题checkbox ...
- 软件架构师必备素质 架构是厂长、开发是妈妈、产品经理是爸爸、测试是医生、产品是孩子、小姨子是培训师、护士是运维
- 使用asp.net提供的MD5实现加密计算
- Yii學習筆記(二)
- Java设计模式-外观模式-facade
- 在iPhone程序中使用后台音乐播放和VoIP
- PL/SQL内置函数
- C# CGI+
- JQuery 判断checkbox是否选中,checkbox全选,获取checkbox选中值
- 一致性哈希算法(Consistent Hashing)
- 对 iOS 多任务的误解 [多任务原理]
- 盖茨留给在校大学生的十句警告
- 搜狗笔试:有两个数,A和B,六种操作分别是+12,-12,+7,-7,+5,-5。A经过若干次操作,变成B
- 为 SELECT 对象增加或删除选项的方法在各浏览器中的支持情况不同