package api import ( "encoding/json" "fmt" "net/http" "time" ) type VideoData struct { Code int `json:"code"` Message string `json:"message"` Ttl int `json:"ttl"` Data struct { Bvid string `json:"bvid"` Aid int `json:"aid"` Videos int `json:"videos"` Tid int `json:"tid"` Tname string `json:"tname"` Copyright int `json:"copyright"` Pic string `json:"pic"` Title string `json:"title"` Pubdate int `json:"pubdate"` Ctime int `json:"ctime"` Desc string `json:"desc"` DescV2 []struct { RawText string `json:"raw_text"` Type int `json:"type"` BizId int `json:"biz_id"` } `json:"desc_v2"` State int `json:"state"` Duration int `json:"duration"` MissionId int `json:"mission_id"` Rights struct { Bp int `json:"bp"` Elec int `json:"elec"` Download int `json:"download"` Movie int `json:"movie"` Pay int `json:"pay"` Hd5 int `json:"hd5"` NoReprint int `json:"no_reprint"` Autoplay int `json:"autoplay"` UgcPay int `json:"ugc_pay"` IsCooperation int `json:"is_cooperation"` UgcPayPreview int `json:"ugc_pay_preview"` NoBackground int `json:"no_background"` CleanMode int `json:"clean_mode"` IsSteinGate int `json:"is_stein_gate"` Is360 int `json:"is_360"` NoShare int `json:"no_share"` ArcPay int `json:"arc_pay"` FreeWatch int `json:"free_watch"` } `json:"rights"` Owner struct { Mid int `json:"mid"` Name string `json:"name"` Face string `json:"face"` } `json:"owner"` Stat struct { Aid int `json:"aid"` View int `json:"view"` Danmaku int `json:"danmaku"` Reply int `json:"reply"` Favorite int `json:"favorite"` Coin int `json:"coin"` Share int `json:"share"` NowRank int `json:"now_rank"` HisRank int `json:"his_rank"` Like int `json:"like"` Dislike int `json:"dislike"` Evaluation string `json:"evaluation"` Vt int `json:"vt"` } `json:"stat"` ArgueInfo struct { ArgueMsg string `json:"argue_msg"` ArgueType int `json:"argue_type"` ArgueLink string `json:"argue_link"` } `json:"argue_info"` Dynamic string `json:"dynamic"` Cid int `json:"cid"` Dimension struct { Width int `json:"width"` Height int `json:"height"` Rotate int `json:"rotate"` } `json:"dimension"` Premiere interface{} `json:"premiere"` TeenageMode int `json:"teenage_mode"` IsChargeableSeason bool `json:"is_chargeable_season"` IsStory bool `json:"is_story"` IsUpowerExclusive bool `json:"is_upower_exclusive"` IsUpowerPlay bool `json:"is_upower_play"` IsUpowerPreview bool `json:"is_upower_preview"` EnableVt int `json:"enable_vt"` VtDisplay string `json:"vt_display"` NoCache bool `json:"no_cache"` Pages []struct { Cid int `json:"cid"` Page int `json:"page"` From string `json:"from"` Part string `json:"part"` Duration int `json:"duration"` Vid string `json:"vid"` Weblink string `json:"weblink"` Dimension struct { Width int `json:"width"` Height int `json:"height"` Rotate int `json:"rotate"` } `json:"dimension"` FirstFrame string `json:"first_frame"` } `json:"pages"` Subtitle struct { AllowSubmit bool `json:"allow_submit"` List []struct { Id int64 `json:"id"` Lan string `json:"lan"` LanDoc string `json:"lan_doc"` IsLock bool `json:"is_lock"` SubtitleUrl string `json:"subtitle_url"` Type int `json:"type"` IdStr string `json:"id_str"` AiType int `json:"ai_type"` AiStatus int `json:"ai_status"` Author struct { Mid int `json:"mid"` Name string `json:"name"` Sex string `json:"sex"` Face string `json:"face"` Sign string `json:"sign"` Rank int `json:"rank"` Birthday int `json:"birthday"` IsFakeAccount int `json:"is_fake_account"` IsDeleted int `json:"is_deleted"` InRegAudit int `json:"in_reg_audit"` IsSeniorMember int `json:"is_senior_member"` } `json:"author"` } `json:"list"` } `json:"subtitle"` Label struct { Type int `json:"type"` } `json:"label"` IsSeasonDisplay bool `json:"is_season_display"` UserGarb struct { UrlImageAniCut string `json:"url_image_ani_cut"` } `json:"user_garb"` HonorReply struct { Honor []struct { Aid int `json:"aid"` Type int `json:"type"` Desc string `json:"desc"` WeeklyRecommendNum int `json:"weekly_recommend_num"` } `json:"honor"` } `json:"honor_reply"` LikeIcon string `json:"like_icon"` NeedJumpBv bool `json:"need_jump_bv"` DisableShowUpInfo bool `json:"disable_show_up_info"` IsStoryPlay int `json:"is_story_play"` } `json:"data"` } type VideoInfo struct { Owner string `json:"owner"` Face string `json:"face"` Title string `json:"title"` Desc string `json:"desc"` Duration string `json:"duration"` Pic string `json:"pic"` Coin int `json:"coin"` Danmaku int `json:"danmaku"` Favorite int `json:"favorite"` Like int `json:"like"` Reply int `json:"reply"` Share int `json:"share"` View int `json:"view"` } func secondsToTimeString(seconds int) string { duration := time.Duration(seconds) * time.Second if duration.Hours() < 1 { return fmt.Sprintf("%02d:%02d", int(duration.Minutes()), int(duration.Seconds())%60) } return fmt.Sprintf("%02d:%02d:%02d", int(duration.Hours()), int(duration.Minutes())%60, int(duration.Seconds())%60) } func GetVideoData(w http.ResponseWriter, r *http.Request) { if err := r.ParseForm(); err != nil { http.Error(w, "参数解析错误", http.StatusInternalServerError) } bv_id := r.Form.Get("bvid") resp, err := http.Get("https://api.bilibili.com/x/web-interface/view?bvid=" + bv_id) if err != nil { http.Error(w, "无法获取视频数据", http.StatusInternalServerError) return } defer resp.Body.Close() var video VideoData err = json.NewDecoder(resp.Body).Decode(&video) // 使用json.NewDecoder解码JSON数据 if err != nil { http.Error(w, "无法解析视频数据", http.StatusInternalServerError) return } imageurl := "https://images.weserv.nl/?url=" info := &VideoInfo{ Owner: video.Data.Owner.Name, Face: imageurl + video.Data.Owner.Face, Title: video.Data.Title, Desc: video.Data.Desc, Duration: secondsToTimeString(video.Data.Duration), Pic: imageurl + video.Data.Pic, Coin: video.Data.Stat.Coin, Danmaku: video.Data.Stat.Danmaku, Favorite: video.Data.Stat.Favorite, Like: video.Data.Stat.Like, Reply: video.Data.Stat.Reply, Share: video.Data.Stat.Share, View: video.Data.Stat.View, } // 如果需要返回JSON数据给客户端,可以使用以下代码 w.Header().Set("Content-Type", "application/json;charset=utf-8") err = json.NewEncoder(w).Encode(info) if err != nil { http.Error(w, "无法解析视频数据", http.StatusInternalServerError) } } func BilibiliInit() { http.HandleFunc("/api/bilibili", GetVideoData) }