记录抖音视频接口的Q&A|青训营笔记

118 阅读2分钟

这是我参与「第三届青训营 -后端场」笔记创作活动的的第4篇笔记。

1、关于mysql无法处理time类型的解决方式:

设置数据库参数

DataSource: root:1026@tcp(localhost:3306)/douyin?charset=utf8mb4&parseTime=True&loc=Local

2、go-zero自带的handler解析方法无法获取MultipartForm参数,手动获取报文参数:

r.ParseMultipartForm(128)
paraMap := r.MultipartForm
req.Token = paraMap.Value["token"][0]
req.Title = paraMap.Value["title"][0]
ptr := paraMap.File["data"][0]
//视频流文件
file, err := ptr.Open()
data, err := ioutil.ReadAll(file)

3、为了保证视频图片的唯一性,我们采用video_id+时间戳的命名方式存放在数据库中:

name := strconv.Itoa(int(user_id)) + strconv.Itoa(int(time.Now().Unix()))
//保存视频文件到本地
err = ioutil.WriteFile(types.SavePlayURL+name+".mp4", req.Data, 0644)

4、关于视频封面,我们采用ffmpeg音视频工具对视频流帧进行封面的抓取,这里简单的模拟cmd抓取视频的第一帧生成图片并保存到本地:

cmd := exec.Command("ffmpeg", "-i", types.SavePlayURL+name+".mp4", "-vframes", "1", "-f", "image2", types.SaveCoverURL+name+".png")
fmt.Println(cmd)
if err := cmd.Start(); err != nil { // 运行命令
   log.Fatal(err)
}

5、数据库中存放获取视频及图片的路由地址:

publishVideo := model.Video{
   CreateTime:    time.Now(),
   UserId:        user_id,
   PlayUrl:       types.PlayURL + name + ".mp4",
   CoverUrl:      types.CoverURL + name + ".png",
   FavoriteCount: 0,
   CommentCount:  0,
   Title:         req.Title,
}

6、安卓模拟器的抖声app访问本地端口时,不能使用本地的ip地址:

模拟器访问本地端口时,会受到防火墙的阻拦,需要采用10.0.2.2的地址进行访问。

7、api到本地路径的路由转换:

server.AddRoutes(
   []rest.Route{
      {
         Method:  http.MethodGet,
         Path:    "/static/play/:id",
         Handler: func(svcCtx *svc.ServiceContext) http.HandlerFunc {
            return func(w http.ResponseWriter, r *http.Request) {
               type my_req struct {
                  id string `path:"id"`
               }
               //var req my_req
               strs := strings.Split(r.URL.Path, "/")
               fmt.Println(strs[len(strs)-1])
               /**if err := httpx.ParsePath(r, &req); err != nil {
                  fmt.Println(err)
                  httpx.Error(w, err)
                  return
               }**/
               http.ServeFile(w, r, types.SavePlayURL + strs[len(strs)-1])
            }
         }(serverCtx),
      },
)

7、最后将返回feed流中最后一条视频的创建时间,作为下一次latest_time时间戳对返回feed流进行限制;若已经没有视频了,则返回time.Now()作为时间戳,重头开始刷取视频:

if len(videos) == 0 {
   nextTime = time.Now()
} else {
   nextTime = videos[len(videos)-1].CreateTime
}