387 lines
8.8 KiB
TypeScript
387 lines
8.8 KiB
TypeScript
export interface ControlReq {
|
|
appid?: string;
|
|
asy_upload?: number;
|
|
biz_req?: BizReq;
|
|
check_type?: number;
|
|
checksum?: string;
|
|
cmd?: string;
|
|
env?: Env;
|
|
file_len?: number;
|
|
model?: number;
|
|
session?: string;
|
|
token?: Token;
|
|
uin?: string;
|
|
}
|
|
|
|
export interface BizReq {
|
|
iAlbumTypeID: number;
|
|
iBatchID: number;
|
|
iBitmap: number;
|
|
iDistinctUse: number;
|
|
iNeedFeeds?: number;
|
|
iPicHight: number;
|
|
iPicWidth: number;
|
|
iUploadTime: number;
|
|
iUploadType: number;
|
|
iUpPicType: number;
|
|
iWaterType: number;
|
|
mapExt?: MapExt;
|
|
mutliPicInfo?: MutliPicInfo;
|
|
sAlbumID: string;
|
|
sAlbumName: string;
|
|
sPicDesc: string;
|
|
sPicPath: string;
|
|
sPicTitle: string;
|
|
stExtendInfo?: StExtendInfo;
|
|
// 视频主体上传专用
|
|
extend_info?: VideoExtendInfo;
|
|
iFlag?: number;
|
|
iIsFormatF20?: number;
|
|
iIsNew?: number;
|
|
iIsOriginalVideo?: number;
|
|
iPlayTime?: number;
|
|
sCoverUrl?: string;
|
|
sDesc?: string;
|
|
sTitle?: string;
|
|
// 视频封面二段上传专用
|
|
stExternalMapExt?: StExternalMapExt;
|
|
sExif_CameraMaker?: string;
|
|
sExif_CameraModel?: string;
|
|
sExif_Latitude?: string;
|
|
sExif_LatitudeRef?: string;
|
|
sExif_Longitude?: string;
|
|
sExif_LongitudeRef?: string;
|
|
sExif_Time?: string;
|
|
}
|
|
|
|
// 多图同批上传时描述「本批共几张 / 当前第几张」,相册里据此合并成同一条
|
|
export interface MutliPicInfo {
|
|
iBatUploadNum: string;
|
|
iCurUpload: string;
|
|
iSuccNum: number;
|
|
iFailNum: number;
|
|
}
|
|
|
|
// 视频主体上传用(视频不走 stExtendInfo.mapParams,而是这段扩展信息)
|
|
export interface VideoExtendInfo {
|
|
video_type: string;
|
|
domainid: string;
|
|
photo_num: string;
|
|
video_num: string;
|
|
batch_num: string;
|
|
qun_id: string;
|
|
}
|
|
|
|
// 视频封面二段上传用:声明这是客户端上传的封面,且与图片混合在同一条动态里
|
|
export interface StExternalMapExt {
|
|
is_client_upload_cover: string;
|
|
is_pic_video_mix_feeds: string;
|
|
}
|
|
|
|
export interface MapExt {
|
|
appid: string;
|
|
userid: string;
|
|
}
|
|
|
|
export interface StExtendInfo {
|
|
mapParams: MapParams;
|
|
}
|
|
|
|
export interface MapParams {
|
|
batch_num: string;
|
|
photo_num: string;
|
|
video_num: string;
|
|
// 视频封面二段上传时用它把封面挂到已上传的视频上
|
|
vid?: string;
|
|
}
|
|
|
|
export interface Env {
|
|
deviceInfo: string;
|
|
refer: string;
|
|
}
|
|
|
|
export interface Token {
|
|
appid: number;
|
|
data: string;
|
|
type: number;
|
|
}
|
|
|
|
// 一次上传的批次信息:同批的多张图必须共用 batchId,相册里才会显示成同一条。
|
|
export interface QunAlbumBatch {
|
|
batchId: number,
|
|
count: string,
|
|
index: string
|
|
}
|
|
|
|
let lastQunAlbumBatchId = 0;
|
|
|
|
// 批次号取秒级时间戳。同一秒里发起的两次上传要错开,不然会被相册并成同一条
|
|
export function nextQunAlbumBatchId () {
|
|
lastQunAlbumBatchId = Math.max(Math.floor(Date.now() / 1000), lastQunAlbumBatchId + 1);
|
|
return lastQunAlbumBatchId;
|
|
}
|
|
|
|
// control_req 的外层(鉴权、来源、会话),图片、视频、封面都一样
|
|
function buildQunAlbumControlReq (
|
|
{ uin, pskey, appid, checksum, check_type, file_len, refer = 'qzone', cmd }: {
|
|
uin: string,
|
|
pskey: string,
|
|
appid: string,
|
|
checksum: string,
|
|
check_type: number,
|
|
file_len: number,
|
|
refer?: string,
|
|
cmd?: string
|
|
},
|
|
biz_req: BizReq
|
|
): ControlReq {
|
|
const req: ControlReq = {
|
|
uin,
|
|
token: { type: 4, data: pskey, appid: 5 },
|
|
appid,
|
|
checksum,
|
|
check_type,
|
|
file_len,
|
|
env: { refer, deviceInfo: 'h5' },
|
|
model: 0,
|
|
biz_req,
|
|
session: '',
|
|
asy_upload: 0,
|
|
};
|
|
if (cmd) req.cmd = cmd;
|
|
return req;
|
|
}
|
|
|
|
// biz_req 里三种上传都要带的基础字段
|
|
function buildQunAlbumBizBase (
|
|
{ iUploadType, sAlbumName = '', sAlbumID = '', iBatchID = 0, sPicTitle = '' }: {
|
|
iUploadType: number,
|
|
sAlbumName?: string,
|
|
sAlbumID?: string,
|
|
iBatchID?: number,
|
|
sPicTitle?: string
|
|
}
|
|
): BizReq {
|
|
return {
|
|
sPicTitle,
|
|
sPicDesc: '',
|
|
sAlbumName,
|
|
sAlbumID,
|
|
iAlbumTypeID: 0,
|
|
iBitmap: 0,
|
|
iUploadType,
|
|
iUpPicType: 0,
|
|
iBatchID,
|
|
sPicPath: '',
|
|
iPicWidth: 0,
|
|
iPicHight: 0,
|
|
iWaterType: 0,
|
|
iDistinctUse: 0,
|
|
iUploadTime: Math.floor(Date.now() / 1000),
|
|
};
|
|
}
|
|
|
|
// 进相册的那一步(图片、视频封面)要带的群与批次信息
|
|
function buildQunAlbumFeedFields (group_id: string, mapParams: MapParams, batchIndex: string) {
|
|
return {
|
|
iNeedFeeds: 1,
|
|
mapExt: { appid: 'qun', userid: group_id },
|
|
stExtendInfo: { mapParams },
|
|
mutliPicInfo: {
|
|
iBatUploadNum: mapParams.batch_num,
|
|
iCurUpload: batchIndex,
|
|
iSuccNum: 0,
|
|
iFailNum: 0,
|
|
},
|
|
};
|
|
}
|
|
|
|
export function qunAlbumControl ({
|
|
uin,
|
|
group_id,
|
|
pskey,
|
|
pic_md5,
|
|
img_size,
|
|
img_name,
|
|
sAlbumName,
|
|
sAlbumID,
|
|
photo_num = '1',
|
|
video_num = '0',
|
|
batch_num = '1',
|
|
batchId = nextQunAlbumBatchId(),
|
|
batchIndex = '0',
|
|
}: {
|
|
uin: string,
|
|
group_id: string,
|
|
pskey: string,
|
|
pic_md5: string,
|
|
img_size: number,
|
|
img_name: string,
|
|
sAlbumName: string,
|
|
sAlbumID: string,
|
|
photo_num?: string,
|
|
video_num?: string,
|
|
batch_num?: string,
|
|
batchId?: number,
|
|
batchIndex?: string
|
|
}
|
|
): {
|
|
control_req: ControlReq[]
|
|
} {
|
|
return {
|
|
control_req: [buildQunAlbumControlReq(
|
|
{ uin, pskey, appid: 'qun', checksum: pic_md5, check_type: 0, file_len: img_size, cmd: 'FileUpload' },
|
|
{
|
|
...buildQunAlbumBizBase({ iUploadType: 0, sAlbumName, sAlbumID, iBatchID: batchId, sPicTitle: img_name }),
|
|
...buildQunAlbumFeedFields(group_id, { photo_num, video_num, batch_num }, batchIndex),
|
|
}
|
|
)],
|
|
};
|
|
}
|
|
|
|
export function createStreamUpload (
|
|
{
|
|
uin,
|
|
session,
|
|
offset,
|
|
seq,
|
|
end,
|
|
slice_size,
|
|
data,
|
|
|
|
}: { uin: string, session: string, offset: number, seq: number, end: number, slice_size: number, data: string }
|
|
) {
|
|
return {
|
|
uin,
|
|
appid: 'qun',
|
|
session,
|
|
offset, // 分片起始位置
|
|
data, // base64编码数据
|
|
checksum: '',
|
|
check_type: 0,
|
|
retry: 0, // 重试次数
|
|
seq, // 分片序号
|
|
end, // 分片结束位置 文件总大小
|
|
cmd: 'FileUpload',
|
|
slice_size, // 分片大小16KB 16384
|
|
biz_req: {
|
|
iUploadType: 3,
|
|
},
|
|
};
|
|
}
|
|
|
|
/**
|
|
* 视频主体上传的控制体。
|
|
*
|
|
* 视频这一步不进相册(相册留空,iBatchID 为 0),只是先把视频传成素材;
|
|
* 分片响应里拿到 sVid 后,再由封面上传(qunAlbumVideoCoverControl)把视频挂进相册。
|
|
*/
|
|
export function qunAlbumVideoControl ({
|
|
uin,
|
|
group_id,
|
|
pskey,
|
|
video_sha1,
|
|
video_size,
|
|
play_time = 0,
|
|
photo_num = '0',
|
|
video_num = '1',
|
|
batch_num = '1',
|
|
}: {
|
|
uin: string,
|
|
group_id: string,
|
|
pskey: string,
|
|
video_sha1: string,
|
|
video_size: number,
|
|
play_time?: number,
|
|
photo_num?: string,
|
|
video_num?: string,
|
|
batch_num?: string
|
|
}): {
|
|
control_req: ControlReq[]
|
|
} {
|
|
return {
|
|
control_req: [buildQunAlbumControlReq(
|
|
{ uin, pskey, appid: 'video_qun', checksum: video_sha1, check_type: 1, file_len: video_size, cmd: 'FileUploadVideo' },
|
|
{
|
|
...buildQunAlbumBizBase({ iUploadType: 3 }),
|
|
sTitle: '',
|
|
sDesc: '',
|
|
sCoverUrl: '',
|
|
iFlag: 0,
|
|
iPlayTime: play_time,
|
|
iIsNew: 111,
|
|
iIsOriginalVideo: 0,
|
|
iIsFormatF20: 0,
|
|
extend_info: {
|
|
video_type: '3',
|
|
domainid: '5',
|
|
photo_num,
|
|
video_num,
|
|
batch_num,
|
|
qun_id: group_id,
|
|
},
|
|
}
|
|
)],
|
|
};
|
|
}
|
|
|
|
/**
|
|
* 视频封面上传的控制体。
|
|
*
|
|
* 按图片上传,但 iUploadType 为 2,并用 mapParams.vid 指向已上传的视频。
|
|
* 相册和批次号只在这一步出现,视频是靠封面进的相册。
|
|
*/
|
|
export function qunAlbumVideoCoverControl ({
|
|
uin,
|
|
group_id,
|
|
pskey,
|
|
sAlbumName,
|
|
sAlbumID,
|
|
cover_md5,
|
|
cover_size,
|
|
vid,
|
|
batchId = nextQunAlbumBatchId(),
|
|
batchIndex = '0',
|
|
photo_num = '0',
|
|
video_num = '1',
|
|
batch_num = '1',
|
|
}: {
|
|
uin: string,
|
|
group_id: string,
|
|
pskey: string,
|
|
sAlbumName: string,
|
|
sAlbumID: string,
|
|
cover_md5: string,
|
|
cover_size: number,
|
|
vid: string,
|
|
batchId?: number,
|
|
batchIndex?: string,
|
|
photo_num?: string,
|
|
video_num?: string,
|
|
batch_num?: string
|
|
}): {
|
|
control_req: ControlReq[]
|
|
} {
|
|
return {
|
|
control_req: [buildQunAlbumControlReq(
|
|
{ uin, pskey, appid: 'qun', checksum: cover_md5, check_type: 0, file_len: cover_size, refer: 'huodong' },
|
|
{
|
|
...buildQunAlbumBizBase({ iUploadType: 2, sAlbumName, sAlbumID, iBatchID: batchId }),
|
|
...buildQunAlbumFeedFields(group_id, { vid, photo_num, video_num, batch_num }, batchIndex),
|
|
// 标明封面由客户端上传,且允许和图片出现在同一条动态里
|
|
stExternalMapExt: {
|
|
is_client_upload_cover: '1',
|
|
is_pic_video_mix_feeds: '1',
|
|
},
|
|
sExif_CameraMaker: '',
|
|
sExif_CameraModel: '',
|
|
sExif_Time: '',
|
|
sExif_LatitudeRef: '',
|
|
sExif_Latitude: '',
|
|
sExif_LongitudeRef: '',
|
|
sExif_Longitude: '',
|
|
}
|
|
)],
|
|
};
|
|
}
|