go 大文件分片上传至服务端

文件分割

分片上传需要先将文件分割为小块[]byte

    //移动指针到开头
    m.File.Seek(0, 0)
    // 切片 每次上传5M
    fileChunk := 5 * (1 << 20)

    // 文件分割 多少份
    totalPartsNum := uint64(math.Ceil(float64(m.Size) / float64(fileChunk)))
    // 根据分割文件数创建channel
    var ch = make(chan error, totalPartsNum)

    for i := uint64(0); i < totalPartsNum; i++ {
        // 计算本次上传 文件大小
        partSize := int(math.Min(float64(fileChunk), float64(m.Size-int64(i*uint64(fileChunk)))))
        // 创建本次上传的[]byte
        partBuffer := make([]byte, partSize)
        // 将文件读取到[]byte   因为File.Read读取后指针停留在最后读取的位置,所以下次直接读取会接着上次的继续读取
        m.File.Read(partBuffer)
        // 使用使用携程一次性上传
        go m.doVideoUpload(partBuffer, partSize, int(totalPartsNum), int(i), ch)

    }
    for v := 0; v < int(totalPartsNum); v++ {
        err := <-ch
        if err != nil {
            return err
        }
    }

使用携程将全部分片上传至远端

func (m *MPUploadVideo) doVideoUpload(FileBuff []byte, partSize int, chunks int, chunk int, ch chan error) {
    var err error
    defer func() {
        ch <- err
    }()

    Url := "https://*/uploadpart"
    client := &http.Client{Timeout: 120 * time.Second}
    urlValues := url.Values{}
    urlValues.Add("name", m.Filename)
    urlValues.Add("type", "video/mp4")
    urlValues.Add("lastModifiedDate", time.Now().Format("Mon Jan 02 2006 15:04:05 GMT +0800")+"中国标准时间")
    urlValues.Add("size", strconv.Itoa(partSize))
    urlValues.Add("partnum", strconv.Itoa(chunk+1))
    urlValues.Add("chunks", strconv.Itoa(chunks))
    urlValues.Add("chunk", strconv.Itoa(chunk))
    urlValues.Add("filename", m.VideoUploadInfo.FileName)
    urlValues.Add("ukey", m.VideoUploadInfo.Ukey)
    mediaArg := MediaArg{}
    mediaArg.Px = []px{
        {
            MinW: m.FileInfo.Width,
            MaxW: m.FileInfo.Width,
            MinH: m.FileInfo.Height,
            MaxH: m.FileInfo.Height,
        },
    }
    mediaArg.Size.Min = partSize
    mediaArg.Size.Max = partSize
    mediaArg.Duration.Max = int(m.FileInfo.Duration)
    mediaArg.Duration.Min = int(m.FileInfo.Duration)
    mediaArg.Profile = "High"
    mediaArg.BitRate = 1228800
    mediaArgStr, _ := json.Marshal(mediaArg)
    urlValues.Add("media_arg", string(mediaArgStr))
    UrlParam := urlValues.Encode()

    req, _ := http.NewRequest("POST", Url+"?"+UrlParam, bytes.NewReader(FileBuff))

    req.Header.Set("content-sha1", utils.GetBytesSha1(FileBuff))
    req.Header.Set("x-arguments", m.XArguments)
    req.Header.Set("Content-Type", "application/octet-stream")
    resp, err := client.Do(req)
    if err != nil {
        return
    }
    //
    body, _ := ioutil.ReadAll(resp.Body)
    defer resp.Body.Close()
    var resDoVidoeUpload ResDoVidoeUpload
    unmarshal1Err := json.Unmarshal([]byte(body), &resDoVidoeUpload)
    if unmarshal1Err != nil {
        err = errors.New("上传视频:失败")
        return
    }
    if resDoVidoeUpload.Code != 0 {
        err = errors.New("上传视频:失败,msg:" + resDoVidoeUpload.Msg)
        return
    }
    m.PartShas = append(m.PartShas, FinishPartsList{
        PartNum: chunk + 1,
        PartSha: resDoVidoeUpload.PartSha,
    })

    return
}
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇