diff --git a/client/highway.go b/client/highway.go index b733e754..c7a4ccbb 100644 --- a/client/highway.go +++ b/client/highway.go @@ -186,10 +186,16 @@ func (c *QQClient) highwayUploadByBDH(stream io.ReadSeeker, cmdId int32, ticket, return rspExt, nil } -func (c *QQClient) highwayUploadFileMultiThreadingByBDH(path string, cmdId int32, threadCount int, ticket, ext []byte) ([]byte, error) { +func (c *QQClient) highwayUploadFileMultiThreadingByBDH(path string, cmdId int32, threadCount int, ticket, ext []byte, encrypt bool) ([]byte, error) { if len(c.srvSsoAddrs) == 0 { return nil, errors.New("srv addrs not found. maybe miss some packet?") } + if encrypt { + if c.highwaySession == nil || len(c.highwaySession.SessionKey) == 0 { + return nil, errors.New("session key not found. maybe miss some packet?") + } + ext = binary.NewTeaCipher(c.highwaySession.SessionKey).Encrypt(ext) + } stat, err := os.Stat(path) if err != nil { return nil, errors.Wrap(err, "get stat error") diff --git a/client/image.go b/client/image.go index f5e9ebd7..b941f14a 100644 --- a/client/image.go +++ b/client/image.go @@ -86,7 +86,7 @@ func (c *QQClient) UploadGroupImageByFile(groupCode int64, path string) (*messag c.srvSsoAddrs = append(c.srvSsoAddrs, fmt.Sprintf("%v:%v", binary.UInt32ToIPV4Address(uint32(addr)), rsp.UploadPort[i])) } } - if _, err = c.highwayUploadFileMultiThreadingByBDH(path, 2, 4, rsp.UploadKey, EmptyBytes); err == nil { + if _, err = c.highwayUploadFileMultiThreadingByBDH(path, 2, 4, rsp.UploadKey, EmptyBytes, false); err == nil { goto ok } return nil, errors.New("upload failed") diff --git a/client/ptt.go b/client/ptt.go index ac14e7a7..f48ee841 100644 --- a/client/ptt.go +++ b/client/ptt.go @@ -14,6 +14,7 @@ import ( "github.com/pkg/errors" "google.golang.org/protobuf/proto" "io" + "os" ) func init() { @@ -88,9 +89,15 @@ ok: }}, nil } -func (c *QQClient) UploadGroupShortVideo(groupCode int64, video, thumb io.ReadSeeker) (*message.ShortVideoElement, error) { +// UploadGroupShortVideo 将视频和封面上传到服务器, 返回 message.ShortVideoElement 可直接发送 +// combinedCache 本地文件缓存, 设置后可多线程上传 +func (c *QQClient) UploadGroupShortVideo(groupCode int64, video, thumb io.ReadSeeker, combinedCache ...string) (*message.ShortVideoElement, error) { videoHash, videoLen := utils.GetMd5AndLength(video) thumbHash, thumbLen := utils.GetMd5AndLength(thumb) + cache := "" + if len(combinedCache) > 0 { + cache = combinedCache[0] + } i, err := c.sendAndWait(c.buildPttGroupShortVideoUploadReqPacket(videoHash, thumbHash, groupCode, videoLen, thumbLen)) if err != nil { return nil, errors.Wrap(err, "upload req error") @@ -106,7 +113,22 @@ func (c *QQClient) UploadGroupShortVideo(groupCode int64, video, thumb io.ReadSe }, nil } ext, _ := proto.Marshal(c.buildPttGroupShortVideoProto(videoHash, thumbHash, groupCode, videoLen, thumbLen).PttShortVideoUploadReq) - hwRsp, err := c.highwayUploadByBDH(utils.MultiReadSeeker(thumb, video), 25, c.highwaySession.SigSession, ext, true) + var hwRsp []byte + if cache != "" { + file, err := os.OpenFile(cache, os.O_WRONLY|os.O_CREATE, 0666) + cp := func() error { + _, err := io.Copy(file, utils.MultiReadSeeker(thumb, video)) + return err + } + if err != nil || cp() != nil { + hwRsp, err = c.highwayUploadByBDH(utils.MultiReadSeeker(thumb, video), 25, c.highwaySession.SigSession, ext, true) + } else { + hwRsp, err = c.highwayUploadFileMultiThreadingByBDH(cache, 25, 8, c.highwaySession.SigSession, ext, true) + _ = os.Remove(cache) + } + } else { + hwRsp, err = c.highwayUploadByBDH(utils.MultiReadSeeker(thumb, video), 25, c.highwaySession.SigSession, ext, true) + } if err != nil { return nil, errors.Wrap(err, "upload video file error") }