发送 file 类型的 message 时,file 自己传入的 metadata 中 duration 为 0

根据路径创建语音消息,发送成功后也没有duration, 我在创建AVFile 对象的时候,添加了 attrubutes[@"duration"] = @(2.3);
发送完成后 AVFile 对象里的duration 被清空了!

AVFile *file = [AVFile fileWithName:@"" contentsAtPath:_path];
file.metaData[@"duration"] = @(2.3);
file.metaData[@"format"] = @"aac";
AVIMAudioMessage *audioMessage = [AVIMAudioMessage messageWithText:@"" file:file attributes:@{}];

发送消息成功后,回掉方法里打印的duration 为0,

发送成功后,我根据AVFile 的objectId 查询表中的duration 是正常的!

  {
"mime_type": "audio/aac",
"key": "z6B0CFMlVv0mlK8o1R2XGbB.aac",
"ACL": {
  "*": {
    "read": true,
    "write": true
  }
},
"name": "2016-08-08-02-25-40-audio.aac",
"url": "http://ac-lie6brzs.clouddn.com/z6B0CFMlVv0mlK8o1R2XGbB.aac",
"metaData": {
  "duration": 2.262187,
  "fileType": 2,
  "size": 8006,
  "_checksum": "4fdfed5c23c3af7aa19a6962831ef0db",
  "format": "aac"
},
"bucket": "lie6brzs",
"objectId": "57a825e70a2b5800585ebb60",
"createdAt": "2016-08-08T06:25:43.789Z",
"updatedAt": "2016-08-08T06:25:43.789Z" }

相关日志, 如下:

     ------ BEGIN LeanCloud REST Request -------
path: /1.1/fileTokens
curl: curl -k -X POST --dump-header - \
   -H "Accept: application/json" \
   -H "Content-Type: application/json; charset=utf-8" \
   -H "Accept-Language: zh-Hans-CN;q=1, en-CN;q=0.9" \
   -H "User-Agent: AVOS Cloud iOS-v3.3.5 SDK" \
   -H "X-LC-Id: lie6brzsmy14q1t8ukvgr32m" \
   -H "X-LC-Prod: 1" \
   -H "X-LC-Sign: 2c84714b8f3718abf7046af3c04dd898,1470637543595" \
   -d "{\"__type\":\"File\",\"key\":\"z6B0CFMlVv0mlK8o1R2XGbB.aac\",\"name\":\"2016-08-08-02-25-40-audio.aac\",\"mime_type\":\"audio\/aac\",\"metaData\":{\"duration\":2.262187,\"fileType\":2,\"size\":8006,\"_checksum\":\"4fdfed5c23c3af7aa19a6962831ef0db\",\"format\":\"aac\"}}" \
   "https://api.leancloud.cn/1.1/fileTokens"
------ END --------------------------------

------ BEGIN LeanCloud REST Request ------
path: 
curl: curl -k -X POST --dump-header - \
   -H "User-Agent: jike/96 (iPhone; iOS 9.2; Scale/2.00)" \
   -H "Content-Type: multipart/form-data; boundary=Boundary+0xAbCdEfGbOuNdArY" \
   -H "Content-Length: 8515" \
   "https://up.qbox.me"
------ END --------------------------------

2016-08-08 14:25:43.784 jike[44247:327075] [DEBUG] __59-[AVPaasClient performRequest:saveResult:block:retryTimes:]_block_invoke [Line 570] 

------ BEGIN LeanCloud REST Response ------
path: /1.1/fileTokens
cost: 0.185s
response: {
    bucket = lie6brzs;
    createdAt = "2016-08-08T06:25:43.789Z";
    objectId = 57a825e70a2b5800585ebb60;
    provider = qiniu;
    token = "w6ZYeC-arS2makzcotrVJGjQvpsCQeHcPseFRDzJ:Nze538oIT_J00NnsrN0IBvffysc=:eyJzY29wZSI6ImxpZTZicnpzIiwiaW5zZXJ0T25seSI6MSwiZGVhZGxpbmUiOjE0NzA2NDExNDN9";
    "upload_url" = "<null>";
    url = "http://ac-lie6brzs.clouddn.com/z6B0CFMlVv0mlK8o1R2XGbB.aac";
}
------ END --------------------------------

[VBOSE]>[__27-[CMCurlLogger logRequest:]_block_invoke (line:67)] 
============开始请求============
path:https://up.qbox.me
curl:curl -k -X POST --dump-header - \
   -H "User-Agent: jike/96 (iPhone; iOS 9.2; Scale/2.00)" \
   -H "Content-Type: multipart/form-data; boundary=Boundary+0xAbCdEfGbOuNdArY" \
   -H "Content-Length: 8515" \
   -H "X-RNCache: ignore" \
   "https://up.qbox.me"
==============结束==============
[VBOSE]>[-[CMCacheProtocol connection:willCacheResponse:] (line:247)] cachedResponse:<NSCachedURLResponse: 0x7fba3c245c40>
[VBOSE]>[-[CMCacheProtocol connectionDidFinishLoading:] (line:253)] finished load https://up.qbox.me
[VBOSE]>[__33-[CMCurlLogger logResponse:data:]_block_invoke (line:137)] 
===========开始 Community REST Response==========
npath:https://up.qbox.me/
mimeType:application/json
header:{
    "Access-Control-Allow-Headers" = "X-File-Name, X-File-Type, X-File-Size";
    "Access-Control-Allow-Methods" = "OPTIONS, HEAD, POST";
    "Access-Control-Allow-Origin" = "*";
    "Access-Control-Expose-Headers" = "X-Log, X-Reqid";
    "Access-Control-Max-Age" = 2592000;
    "Cache-Control" = "no-store, no-cache, must-revalidate";
    Connection = "keep-alive";
    "Content-Length" = 75;
    "Content-Type" = "application/json";
    Date = "Mon, 08 Aug 2016 06:25:43 GMT";
    Pragma = "no-cache";
    Server = nginx;
    "X-Content-Type-Options" = nosniff;
    "X-Log" = "s.ph;s.put.tw;s.put.tr;s.put.tw;s.put.tr;s.ph;s.put.tw;s.put.tr;s.ph;PFDS;PFDS:1;PFDS:1;rs23_3.sel/not found;rs22_3.sel/not found;rdb.g/no such key;DBD/404;v4.get:1/Document not found;rs23_3.ins;qtbl.ins:2;mc.s;RS:3;rs.put:4;rs-upload.putFile:7;UP:8";
    "X-Reqid" = RCkAANSSVfANwWgU;
}
code:(200)
response:{
  "hash" : "Fp4ASvZX36_63U_KHxqEpObJlIhB",
  "key" : "z6B0CFMlVv0mlK8o1R2XGbB.aac"
}
===========结束===========
2016-08-08 14:25:43.939 jike[44247:327330] [INFO] -[AVIMWebSocketWrapper sendCommand:] [Line 684] 

------ BEGIN LeanCloud IM Out Command ------
cmd: Direc
type: AVIMDirectCommand
content: <AVIMGenericCommand 0x7fba3bdd0560>: {
    cmd: direct
    peerId: "579ea53107961b2d661f39ce"
    directMessage {
      msg: "{"_lctype":-3,"_lcattrs":{"dev":true,"username":"吴文钰"},"_lcfile":{"url":"http://ac-lie6brzs.clouddn.com/z6B0CFMlVv0mlK8o1R2XGbB.aac","objId":"57a825e70a2b5800585ebb60","metaData":{"size":8006,"format":"aac","duration":0}}}"
      cid: "57a18a808ac247005ffe57e7"
      transient: false
    }
}
------ END ---------------------------------

2016-08-08 14:25:43.971 jike[44247:320550] [INFO] -[AVIMWebSocketWrapper webSocket:didReceiveMessage:] [Line 756] 

------ BEGIN LeanCloud IM In Command ------
content: <AVIMGenericCommand 0x7fba3bdcd730>: {
    cmd: ack
    peerId: "579ea53107961b2d661f39ce"
    i: 2
    ackMessage {
      t: 1470637543992
      uid: "Y+6nXu0AQI+CvxAXzRTxBA"
    }
}
------ END --------------------------------

这里的 message 的 duration 是从 file 的 metaData 中取的。
如果是本地路径构建语音消息,SDK 会自动计算 duration 然后将自己存储的 file 的 duration 覆盖掉。

但是我测试不管是自己的 duration 还是 SDK 计算并覆盖的,都可以在消息发送成功后获取到。用的也是和你一模一样的代码。
看日志发送消息时 duration 却变成了 0,不清楚这个情况是怎么出现的。
能否上传一个可以重现问题的 Demo 来看下?

经过测试 我知道原因了,在创建AVFile 对象之前,我调用了
[[NSFileManager defaultManager]
moveItemAtPath:voicePath toPath:path error:nil];

方法,将voiceFile 移动到了一个指定的临时目录里,这个时候,将这个临时目录下的文件创建AVFile 对象,发送AVIMAudioMessage 就会出现我上面说的情况!

这个看起来不是 SDK 的问题。
AVFile 上传的过程是异步的,是否在这个时候进行了什么操作?
请上传一个可以重现情况的 Demo

我发现,如果文件的后缀名不正确,想我上面写的文件没有后缀名,它的duration 就是不对的,
我将文件添加一个后缀名(aac), duration 就正确了!
很奇怪,你们是通过后缀名得到类型,计算长度吗?

我们的 SDK 已经开源了,可以看这里: