NTP时间戳转换
2019-06-15 本文已影响0人
RoaringMe
场景
原理图腾讯视频云直播答题NTP时间同步方案是在推流 URL 之后添加 &txAddTimestamp=2 参数(之前的txAddTimestamp=1会在小程序上遭遇播放黑屏问题),由服务器在视频流每一帧打入一个带有国际标准时间(误差在 100ms 以内)的 SEI 时间戳。通过TXLiteAVSDK的 PLAY_EVT_GET_MESSAGE 消息事件获取的是一个8字节的64位时间戳。以下介绍了如何把这个8字节的64位时间戳转换成Unix时间戳。
iOS转换Unix时间戳
-(void) onPlayEvent:(int)EvtID withParam:(NSDictionary*)param
{
NSDictionary* dict = param;
dispatch_async(dispatch_get_main_queue(), ^{
//消息事件
if (EvtID == PLAY_EVT_GET_MESSAGE) {
//事件戳转换
long tv = [self byteArrayToInt:param[@"EVT_GET_MSG"]];;
long sv = tv / 1000; // 服务器返回的是毫秒Unix timestamp,这里转换成秒
NSLog(@"time %ld", sv);
}
});
}
-(long)byteArrayToInt:(NSData *)data {
Byte *byteArray = (Byte *)data.bytes;
int a_len = 8;
Byte *a = (Byte *)malloc(a_len);
int i = a_len - 1;
int j = (int)data.length - 1;
for (; i >= 0; i--, j--) {// 从b的尾部(即int值的低位)开始copy数据
if (j >= 0)
a[i] = byteArray[j];
else
a[i] = 0;// 如果b.length不足4,则将高位补0
}
// 注意此处和byte数组转换成int的区别在于,下面的转换中要将先将数组中的元素转换成long型再做移位操作,
// 若直接做位移操作将得不到正确结果,因为Java默认操作数字时,若不加声明会将数字作为int型来对待,此处必须注意。
long v0 = (long) (a[0] & 0xff) << 56;// &0xff将byte值无差异转成int,避免Java自动类型提升后,会保留高位的符号位
long v1 = (long) (a[1] & 0xff) << 48;
long v2 = (long) (a[2] & 0xff) << 40;
long v3 = (long) (a[3] & 0xff) << 32;
long v4 = (long) (a[4] & 0xff) << 24;
long v5 = (long) (a[5] & 0xff) << 16;
long v6 = (long) (a[6] & 0xff) << 8;
long v7 = (long) (a[7] & 0xff);
free(a);
return v0 + v1 + v2 + v3 + v4 + v5 + v6 + v7;
}
Android转换Unix时间戳
long timeStamp = byteArrayToInt(param.getByteArray(TXLiveConstants.EVT_GET_MSG));
/**
* 将8字节的byte数组转成一个long值
*/
public static long byteArrayToInt(byte[] byteArray) {
byte[] a = new byte[8];
int i = a.length - 1, j = byteArray.length - 1;
for (; i >= 0; i--, j--) {// 从b的尾部(即int值的低位)开始copy数据
if (j >= 0)
a[i] = byteArray[j];
else
a[i] = 0;// 如果b.length不足4,则将高位补0
}
// 注意此处和byte数组转换成int的区别在于,下面的转换中要将先将数组中的元素转换成long型再做移位操作,
// 若直接做位移操作将得不到正确结果,因为Java默认操作数字时,若不加声明会将数字作为int型来对待,此处必须注意。
long v0 = (long) (a[0] & 0xff) << 56;// &0xff将byte值无差异转成int,避免Java自动类型提升后,会保留高位的符号位
long v1 = (long) (a[1] & 0xff) << 48;
long v2 = (long) (a[2] & 0xff) << 40;
long v3 = (long) (a[3] & 0xff) << 32;
long v4 = (long) (a[4] & 0xff) << 24;
long v5 = (long) (a[5] & 0xff) << 16;
long v6 = (long) (a[6] & 0xff) << 8;
long v7 = (long) (a[7] & 0xff);
return v0 + v1 + v2 + v3 + v4 + v5 + v6 + v7;
}