在对接 微博 广告时,微博给出的代码示例是PHP版本的,没有 java 版本,因此对接时有两个地方容易出问题,
1、视频分片上传
2、视频分片后MD5取值验证不通过。
查询当前网站没有提供相应的参考内容。
注意事项:如果不分片时,初始化接口的MD5值需要和分片MD5值相同。
下面将自己对接时的源码分享出来供大家参考。
视频上传核心代码:
Map<String, Object> initParamsMap = initToken();
AdxCreativeListInfo creativeListInfo = creativeListInfoList.get(0);
initParamsMap.put(WeiboConstants.VideoUpload.NAME, creativeListInfo.getCname());
initParamsMap.put(WeiboConstants.VideoUpload. CHECK , creativeListInfo.getfMd5());
Integer size = creativeListInfo.getSize();
initParamsMap.put(WeiboConstants.VideoUpload.LENGTH, size);
try {
log.info("上传视频-初始化接口,请求参数。");
JSONObject initRetJo = CommonHttpUtil.postJsonResponseObject(weiboConfig.getVideoUploadInitUrl(), initParamsMap);
if (!RetCodeEnum.checkSuccess(initRetJo.getInteger(WeiboConstants.RET_CODE))) {
log.error("上传视频-初始化接口,返回报错。retMst={}", initRetJo.getString(WeiboConstants.RET_MSG));
return;
}
JSONObject initMsg = initRetJo.getJSONObject(WeiboConstants.RET_MSG);
String uploadId = initMsg.getString(WeiboConstants.VideoUpload.UPLOAD_ID);
Integer length = initMsg.getInteger(WeiboConstants.VideoUpload.LENGTH);
file file = new File(tempFilePath + "upload_video/" + creativeListInfo.getCampaignId() + "_" + creativeListInfo.getCname());
inputStream inputStream = new URL(creativeListInfo.getValue()).openStream();
String weiboUrl = StringUtils.EMPTY;
byte uploadStatus = null;
try {
//计算文件分片数
int count = size % length > 0 ? size / length + 1 : size / length;
//获取文件
FileUtils.copyInputStreamToFile(inputStream, file);
Map<String, Object> uploadParamsMap = initToken();
uploadParamsMap.put(WeiboConstants.VideoUpload.UPLOAD_ID, uploadId);
uploadParamsMap.put(WeiboConstants.VideoUpload.LENGTH, length);
uploadParamsMap.put(WeiboConstants.VideoUpload.FILE_LENGTH, size);
uploadParamsMap.put(WeiboConstants.VideoUpload.CHECK, creativeListInfo.getfMd5());
for (int i = 0; i < count; i++) {
uploadParamsMap.put(WeiboConstants.VideoUpload.PART_NUMBER, i);
byte[] block = CommonFileUtils.getBlock(file, i, length);
uploadParamsMap.put(WeiboConstants.VideoUpload.CONTENT, Base64.getEncoder().encodeToString(block));
uploadParamsMap.put(WeiboConstants.VideoUpload.SLICE_CHECK, MD5Utils.phpMd5(block));
log.info("上传视频-调用上传接口,请求参数。");
JSONObject uploadRetJo = CommonHttpUtil.postJsonResponseObject(weiboConfig.getVideoUploadUrl(), uploadParamsMap);
Integer errCode = uploadRetJo.getInteger(WeiboConstants.ERR_CODE);
if (!RetCodeEnum.checkSuccess(uploadRetJo.getInteger(WeiboConstants.RET_CODE)) || 0 != errCode) {
log.error("上传视频-调用上传接口,上传错误。erroCode={}[{}],retMsg={}", errCode, errCodeMap.get(String.valueOf(errCode)), uploadRetJo.getString(WeiboConstants.RET_MSG));
uploadStatus = UploadStatusEnum.Failed_Upload.getStatus();
break;
}
JSONObject uploadMsg = uploadRetJo.getJSONObject(WeiboConstants.RET_MSG);
weiboUrl = uploadMsg.getString(WeiboConstants.VideoUpload.URL);
uploadStatus = UploadStatusEnum.Success_Upload.getStatus();
}
AdxAppWeiboVideo update = new AdxAppWeiboVideo();
update.setId(video.getId());
update.setVideoUrl(weiboUrl);
update.setUploadStatus(uploadStatus);
update.setUploadDate(new Date());
adxAppWeiboVideoService.updateBySelective(update);
} catch (Exception e) {
log.error("上传视频-调用上传接口,异常", e);
} finally {
file.delete();
inputStream. close ();
}
} catch (Exception e) {
log.error("上传视频-初始化接口,报错", e);
}
其中参考封装方法
1、视频分片
byte[] block = CommonFileUtils.getBlock(file, i, length);
/**
* 获取分块文件数组
*
* @param file 文件
* @param offset 起始偏移量
* @param blockSize 分块大小
* @return
*/
public static byte[] getBlock(File file, long offset, int blockSize) {
byte[] result = new byte[blockSize];
RandomAccessFile accessFile = null;
try {
accessFile = new RandomAccessFile(file, "r");
accessFile.seek(offset * blockSize);
int readSize = accessFile.read(result);
if (readSize == -1) {
return null;
} else if (readSize == blockSize) {
return result;
} else {
byte[] tmpByte = new byte[readSize];
System.arraycopy(result, 0, tmpByte, 0, readSize);
return tmpByte;
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (accessFile != null) {
try {
accessFile.close();
} catch (IOException e1) {
}
}
}
return null;
}
2、 md5加密
MD5Utils.phpMd5(block)
/**
* @param input 输入
* @return 返回16个字节
* @throws Exception
*/
public static String phpMd5(byte[] input) throws Exception {
MessageDigest md5 = MessageDigest.getInstance("MD5");
md5.update(input);
/** 获取加密后的字节数组 */
byte[] md5Bytes = md5.digest();
String res = "";
for (int i = 0; i < md5Bytes.length; i++){
int temp = md5Bytes[i] & 0xFF;
// 转化成十六进制不够两位,前面加零
if (temp <= 0XF){
res += "0";
}
res += Integer.toHexString(temp);
}
return res;
}