我需要在mp4容器中读取并注入XMP元数据 .

我知道这可以在Android上使用“mp4parser”库,但我找不到iOS的等价物 .

对于读取部分,是否可以从相机胶卷读取每个素材以快速检查其360 XMP元数据?

为了写作,我正在尝试使用Adobe的XMP工具包 . 我在一个文件夹中有一个mp4视频,我想要注入360个元数据 .

注入metadatas后(我认为它有效),我将视频导出到相机胶卷,但看起来视频转换为m4v并且它丢失了我写的每个元数据 . 它是预期的,还是我的代码错了?

这是代码:

MetadataManager.mm

#import "MetadataManager.h"

#define IOS_ENV 1

#include

#define TXMP_STRING_TYPE std::string

#define XMP_INCLUDE_XMPFILES 1

#include "XMP.incl_cpp"

#include "XMP.hpp"

#include

#include

using namespace std;

@implementation MetadataManager {

}

+ (void)write360Metadatas:(NSString *)filePath {

if (!SXMPMeta::Initialize())

exit(1);

if (!SXMPFiles::Initialize())

exit(1);

SXMPFiles myFile;

XMP_OptionBits opts = kXMPFiles_OpenForUpdate | kXMPFiles_OpenUseSmartHandler;

std::string status = "";

std::string filePathStd = std::string([filePath UTF8String]);

// First, try to open the file

bool ok = myFile.OpenFile(filePathStd, kXMP_UnknownFile, opts);

if( ! ok ){

status += "No smart handler available for " + filePathStd + "\n";

status += "Trying packet scanning.\n";

// Now try using packet scanning

opts = kXMPFiles_OpenForUpdate | kXMPFiles_OpenUsePacketScanning;

ok = myFile.OpenFile(filePathStd, kXMP_UnknownFile, opts);

}

if(ok){

SXMPMeta meta;

myFile.GetXMP( &meta );

displayPropertyValues(&meta);

injectMetadatas(&meta);

// Check we can put the XMP packet back into the file

if(myFile.CanPutXMP(meta))

{

// If so then update the file with the modified XMP

myFile.PutXMP(meta);

}

// Close the SXMPFile. This *must* be called. The XMP is not

// actually written and the disk file is not closed until this call is made.

myFile.CloseFile();

}

}

SXMPMeta createXMPFromRDF()

{

const char * rdf =

"

" xmlns:GSpherical='http://ns.google.com/videos/1.0/spherical/'>"

"true"

"true"

"Spherical Metadata Tool"

"equirectangular"

"

";

SXMPMeta meta;

// Loop over the rdf string and create the XMP object

// 10 characters at a time

int i;

for (i = 0; i < (long)strlen(rdf) - 10; i += 10 )

{

meta.ParseFromBuffer ( &rdf[i], 10, kXMP_ParseMoreBuffers );

}

// The last call has no kXMP_ParseMoreBuffers options, signifying

// this is the last input buffer

meta.ParseFromBuffer ( &rdf[i], (XMP_StringLen) strlen(rdf) - i );

return meta;

}

void injectMetadatas(SXMPMeta * meta)

{

// Add an item onto the dc:creator array

// Note the options used, kXMP_PropArrayIsOrdered, if the array does not exist it will be created

meta->AppendArrayItem(kXMP_NS_DC, "creator", kXMP_PropArrayIsOrdered, "Author Name", 0);

meta->AppendArrayItem(kXMP_NS_DC, "creator", kXMP_PropArrayIsOrdered, "Another Author Name", 0);

// Now update alt-text properties

meta->SetLocalizedText(kXMP_NS_DC, "title", "en", "en-US", "An English title");

meta->SetLocalizedText(kXMP_NS_DC, "title", "fr", "fr-FR", "Un titre Francais");

// Display the properties again to show changes

cout << "After update:" << endl;

displayPropertyValues(meta);

// Create a new XMP object from an RDF string

SXMPMeta rdfMeta = createXMPFromRDF();

// Append the newly created properties onto the original XMP object

// This will:

// a) Add ANY new TOP LEVEL properties in the source (rdfMeta) to the destination (meta)

// b) Replace any top level properties in the source with the matching properties from the destination

SXMPUtils::ApplyTemplate(meta, rdfMeta, kXMPTemplate_AddNewProperties | kXMPTemplate_ReplaceExistingProperties | kXMPTemplate_IncludeInternalProperties);

// Display the properties again to show changes

cout << "After Appending Properties:" << endl;

displayPropertyValues(meta);

}

void displayPropertyValues(SXMPMeta * meta)

{

// Read a simple property

string simpleValue; //Stores the value for the property

meta->GetProperty(kXMP_NS_XMP, "CreatorTool", &simpleValue, 0);

cout << "meta:CreatorTool = " << simpleValue << endl;

// Get the first and second element in the dc:creator array

string elementValue;

meta->GetArrayItem(kXMP_NS_DC, "creator", 1, &elementValue, 0);

if(elementValue != "")

{

cout << "dc:creator[1] = " << elementValue << endl;

meta->GetArrayItem(kXMP_NS_DC, "creator", 2, &elementValue, 0);

cout << "dc:creator[2] = " << elementValue << endl;

}

// Get the the entire dc:subject array

string propValue;

int arrSize = meta->CountArrayItems(kXMP_NS_DC, "subject");

for(int i = 1; i <= arrSize;i++)

{

meta->GetArrayItem(kXMP_NS_DC, "subject", i, &propValue, 0);

cout << "dc:subject[" << i << "] = " << propValue << endl;

}

// Get the dc:title for English and French

string itemValue;

string actualLang;

meta->GetLocalizedText(kXMP_NS_DC, "title", "en", "en-US", 0, &itemValue, 0);

cout << "dc:title in English = " << itemValue << endl;

meta->GetLocalizedText(kXMP_NS_DC, "title", "fr", "fr-FR", 0, &itemValue, 0);

cout << "dc:title in French = " << itemValue << endl;

// Get dc:MetadataDate

XMP_DateTime myDate;

if(meta->GetProperty_Date(kXMP_NS_XMP, "MetadataDate", &myDate, 0))

{

// Convert the date struct into a convenient string and display it

string myDateStr;

SXMPUtils::ConvertFromDate(myDate, &myDateStr);

cout << "meta:MetadataDate = " << myDateStr << endl;

}

cout << "----------------------------------------" << endl;

}

@end

任何帮助将不胜感激,谢谢 .

java如何将mp4写入光盘_iOS - 读取/写入mp4视频的XMP元数据相关推荐

  1. java excel row遍历空_Java poi读取,写入Excel,处理row和cell可能为空的情况

    首先需要导入包 import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.poifs.filesystem.NP ...

  2. Java NIO 读取文件、写入文件、读取写入混合

    前言 Java NIO(new/inputstream outputstream)使用通道.缓冲来操作流,所以要深刻理解这些概念,尤其是,缓冲中的数据结构(当前位置(position).限制(limi ...

  3. java 写入mysql blob_java 读取写入 mysql blob

    2019独角兽企业重金招聘Python工程师标准>>> package com.sohu.smc.test; import java.io.ByteArrayInputStream; ...

  4. NFC读取写入简单使用

    NFC读取写入简单使用 适用于无加密普通NFC卡片数据读取写入 NFC数据读取写入的方法 Demo地址:https://download.csdn.net/download/st526403649/1 ...

  5. java压缩文件读取_用Java读取/写入压缩和非压缩文件

    java压缩文件读取 这篇文章的主要原因是尝试不要重复自己( DRY ),因为通常,我会遇到递归的需求,即读写压缩的和非压缩的文件(主要是JSON和CSV). 首先让我们看看如何读取文本文件. 注意我 ...

  6. 使用Java中的FileChannel和ByteBuffer在文件中读取/写入文件

    过去,我讨论过RandomAccessFile以及如何将其用于在Java中进行更快的IO,在本Java NIO教程中,我们将了解如何通过使用FileChannel和ByteBuffer来使用读/写数据 ...

  7. 用Java读取/写入压缩和非压缩文件

    这篇文章的主要原因是尝试不重复自己( DRY ),因为通常,我会遇到读写压缩和非压缩文件(主要是JSON和CSV)的递归需求. 首先让我们看看如何读取文本文件. 注意我正在使用(相对较小的)文本文件, ...

  8. Java poi读取,写入Excel2003

    Java poi读取,写入Excel2003 相关阅读: poi读写Excel2007:http://www.cnblogs.com/gavinYang/p/3576741.html jxl读写exc ...

  9. java读取txt写入excel,java中对txt和excel的读取和写入

    txt工具类: package com.rj.bd.xm; import java.io.BufferedReader; import java.io.BufferedWriter; import j ...

最新文章

  1. Notification和KVO有什么不同
  2. 拿来就能用! CTO 创业技术栈指南!
  3. P3项目全球模板狗血设置之二 --- 移动类型523收货不能自动创建批次号
  4. python arima模型_时间序列分析 ARIMA模型 Python(2)
  5. dpkg and apt
  6. Asp.Net生命周期系列三
  7. 拆轮子:requests
  8. 使用hiredis接口(Synchronous API)编写redis流水线客户端
  9. matlab绘制有夹角的2个平面,matlab求两向量夹角
  10. 常用ADSS光缆的代表结构和主要参数介绍
  11. PHPStrom 快捷键
  12. python随笔12(传递任意数量的实参)
  13. todo游戏行业实战案例3:玩家等级停滞率
  14. 在 Nebula K8s 集群中使用 nebula-spark-connector 和 nebula-algorithm
  15. 使用ShareSDK实现QQ登录和分享操作
  16. 计算机编程语言排行榜—TIOBE世界编程语言排行榜(2020年6月份最新版)
  17. Factory IO的应用(一)
  18. 计算机考研调剂心酸,考研,这一路走来、辛酸苦辣~百感交集~(转)
  19. 量化交易:如何让回测更贴近实盘结果
  20. 简单实用的PPT框架结构

热门文章

  1. 分享一份软件测试项目(Python项目)
  2. 【总结】个人推荐的接口测试工具和接口性能/压力测试工具
  3. matlab中a2=poly(p2),插值与拟合matlab实现
  4. chart.js报错“Canvas is already in use. Chart ...must be destroyed before the canvas can be reused ”
  5. 苹果手机使用爱思助手安装ipa软件
  6. 标量、向量、矩阵求导
  7. tuple unpacking
  8. eclipse的安装和汉化
  9. STM32 定时器中断相关知识及配置
  10. Android 快速集成谷歌账户登录