iOS技术文章iOS技术交流收藏iOS进阶

AVFoundation与spatial-media写全景MP4

2016-11-10  本文已影响344人  熊皮皮

使用AVAssetWriter虽然可方便地输出MP4文件,不过,对于需要打上全景标识(Spherical Video,由谷歌定义)的场合,却是无能为力。然而,无全景标识的全景视频上传到Youtube或Facebook被当成普通平面视频,则相应的视频播放页面为平面投影,此时用户看到的是全景展开图,显然不符合预期。

针对AVFoundation写全景标识这一需求,经查阅文档,发现AVAssetWriter只支持写预定义的元数据,由metadata属性管理。

@property(nonatomic, copy) NSArray<AVMetadataItem *> *metadata;

AVMetadataItem可接受的元数据键值由AV Foundation Metadata Key Constants表示,它对此作了分类处理,如下所示:

以Key Spaces为例,有下列键值可使用:

查看所有元数据键值可发现,Google定义的Spherical Video并不在MP4或iTunes支持范围内。那么,如何给AVAssetWriter输出的全景MP4文件写入谷歌要求的Spherical Video相关标识呢?谷歌只提供了一个python脚本,我们在应用中直接使用它还是略为麻烦。在此,使用C++移植版spatial-media实现此功能,示例代码如下所示。注意,此库在iOS需要修正些编译错误。

SpatialMedia::Parser parser;
parser.m_strInFile  = "input file";
parser.m_strOutFile = "output file";
if ("" == parser.getInFile()) {
    cout << "Please provide an input file." << endl;
    exit(-1);
}
    
Utils utils;
if (parser.getInject()) {
    if ("" == parser.getOutFile()) {
        cout << "Injecting metadata requires both input and output file." << endl;
        exit(-2);
    }
    Metadata md;
    std::string &strVideoXML = utils.generate_spherical_xml(parser.getStereoMode(), parser.getCrop());
    md.setVideoXML(strVideoXML);
    if (parser.getSpatialAudio())
        md.setAudio(&g_DefAudioMetadata);
    if (strVideoXML.length() > 1)
        utils.inject_metadata(parser.getInFile(), parser.getOutFile(), &md);
    else
        cout << "Failed to generate metadata." << endl;
}
上一篇下一篇

猜你喜欢

热点阅读