Date: 2016-03-23

Title: m4a文件在iOS上的流媒体播放

Tags: m4a, mp4, iOS, Android

URL: m4a-streaming-play-on-mobile-phone

故障

公司项目中有个语音录制与播放的功能,QA反馈有部分 Android 机型录制的音乐文件无法在 iOS 上进行播放。看了一下 iOS 的实现代码,iOS 的实现有考虑当文件较大时先下载再播放引起的延迟,是按流形式播放的。

找到出错的 m4a 文件,发现如果按下载播放形式,不会出现任何问题;按流形式边下边播,会报错:

on-optimized formats not supported for streaming

原因

m4a 文件本质就是一个mp4文件,m4a仅是声明容器文件中仅含有音频内容。mp4和QuickTime®文件一样都是一种容器文件,类似XML那样由若干个"Atom"组成,每个 atom 文件中存放不同的meta、音频数据、视频数据、字幕等内容。而所谓 "optimize for streaming" 意指将文件中的 meta data 提到文件前部,这样播放器按流形式读取时,可以在获取音视频数据前获取具体的音视频编码信息。

mp4 和 QuickTime 可以使用 Appple 公司的 Atom Inspector 工具打开:

左边的001.m4a 文件是播放出错的 m4a 文件,可以看到,用于存入音频数据(AAC格式)的 mdata 牌ftyp 后,而存放 metadata 的 moov 处于文件的最后。

位于右边的文件是使用iTunes转换后的 m4a 文件,moov 段被移动到了文件前部,mdata 被放置于文件的最后。转换后的m4a可以正常按流形式进行播放。

解决

最初是想将文件转换放到服务端来进行,让它类似缩略图生成那样成为一种文件扩展服务。但是,考虑 CS 团队未必有时间马上开发这个扩展功能而项目又等着急用,最后我还是直接在 Android 中实现了这个 optimizing of Streaming 功能。

使用的是mp4parser Library。简单的将文件使用 mp4parser 复制一下音轨即可,因为项目中为用户录音,实际音轨只有一条,所以将那条音轨取出存入一个新文件即可。代码如下:

        Movie originalMovie = MovieCreator.build(sourceM4a);
Movie destMovie = new Movie();
Track audioTrack = originalMovie.getTracks().get(0);
destMovie.addTrack(audioTrack);
Mp4Builder builder = new DefaultMp4Builder();
Container container = builder.build(destMovie);
container.writeContainer(new FileOutputStream(destM4a).getChannel());

m4a文件在iOS上的流媒体播放的更多相关文章

  1. IOS上传文件开发

    IOS上传文件开发     在移动应用开发  文件形式上传是不可缺少的,近期把IOS这块文件上传文件代码简单的整理一下.假设大家有须要安卓这边的代码,本人也能够分享给大家! QQ群:74432915 ...

  2. 细数iOS上的那些安全防护

    细数iOS上的那些安全防护  龙磊,黑雪,蒸米 @阿里巴巴移动安全 0x00 序 随着苹果对iOS系统多年的研发,iOS上的安全防护机制也是越来越多,越来越复杂.这对于刚接触iOS安全的研究人员来说非 ...

  3. 微信双开是定时炸弹?关于非越狱iOS上微信分身高危插件ImgNaix的分析

    作者:蒸米@阿里移动安全 序言 微信作为手机上的第一大应用,有着上亿的用户.并且很多人都不只拥有一个微信帐号,有的微信账号是用于商业的,有的是用于私人的.可惜的是官方版的微信并不支持多开的功能,并且频 ...

  4. 解决protobuf不能直接在IOS上使用,利用protobuf-net在IOS上通讯

    ---------------------------------------------------------------------------------------------------- ...

  5. iOS上简单推送通知(Push Notification)的实现

    iOS上简单推送通知(Push Notification)的实现 根据这篇很好的教程(http://www.raywenderlich.com/3443/apple-push-notification ...

  6. 【转帖】ios上取得设备唯一标志的解决方案

    原文地址:http://lqzit.iteye.com/blog/2070306 注意:keychina设置完之后,项目目录里的“项目名.entitlements”文件不是手动创建出的,而是在按照如下 ...

  7. 转:基于IOS上MDM技术相关资料整理及汇总

    一.MDM相关知识: MDM (Mobile Device Management ),即移动设备管理.在21世纪的今天,数据是企业宝贵的资产,安全问题更是重中之重,在移动互联网时代,员工个人的设备接入 ...

  8. 关于iOS上的静态库

    最近再进行项目的真机调试,然后发现了一个天坑.就此研究了一些iOS上的静态库的使用: 首先我们是直接拿一个可以运行的项目来制作静态库的,网上大部分都是先创建静态库然后再写内容,看看我的方法. 1.把子 ...

  9. 阻止文件不被上传到iCloud-b

    有空用下 http://www.cocoachina.com/bbs/read.php?tid=86244 http://www.ooso.net/archives/617 http://blog.c ...

随机推荐

  1. 被linux线程基础折磨的点滴——还是没得到完美的答案,但至少得到了所需

    #include<sys/types.h> #include<unistd.h> #include<stdio.h> #include<stdlib.h> ...

  2. svn 使用笔记(一)

    检出: svn checkout http://***.***.***.*** path --username *** --password ***   更新: svn update path --f ...

  3. HTML文档的经常使用标记

    一.HTML文档中经常使用的标记有文字标记.段落标记.列表标记.超链接标记.图像标记.表格标记.框架标记和多媒体标记,以下对这些经常使用标记进行介绍: 1.文字标记:文字是网页重要的组成部分之中的一个 ...

  4. Fork of LGPL version of JPedal

    https://github.com/on-site/JPedal —————————————————————————————————————————————————————————————————— ...

  5. js类型转换 之 转数字类型

    手动将各类型 转换成 数字类型 JS提供了三种方法: Number(object); parseInt(string, radix); parseFloat(string, radix). 三种方法具 ...

  6. 关于Cocos2d-x中物理世界的物体乱跳的问题的解决

    这是电脑短时间内帧率低,无法满足游戏配置的帧率引起的. 解决方法: 第一种: 1.打开AppDelegate.cpp文件 2.把director->setAnimationInterval(1. ...

  7. Ubuntu创建新用户并增加管理员权限 删除某个用户

    sudo adduser xxx 这样的命令会在home目录下添加一个帐号sudo useradd xxx 仅仅是添加用户, 不会在home目录添加帐号 删除:终端方法:以下用newuser代替想要删 ...

  8. C++ 数字

    C++ 数字通常,当我们需要用到数字时,我们会使用原始的数据类型,如 int.short.long.float 和 double 等等.这些用于数字的数据类型,其可能的值和数值范围,我们已经在 C++ ...

  9. jquery 中json数组的操作(转)

    在jquery中处理JSON数组的情况中遍历用到的比较多,但是用添加移除这些好像不是太多. 今天试过json[i].remove(),json.remove(i)之后都不行,看网页的DOM对象中好像J ...

  10. 天线增益英文名称:antenna gain

    天线增益是指:在输入功率相等的条件下,实际天线与理想的辐射单元在空间同一点处所产生的信号的功率密度之比.它定量地描述一个天线把输入功率集中辐射的程度.增益显然与天线方向图有密切的关系,方向图主瓣越窄, ...