Blog/api/bilibili.go

232 lines
7.5 KiB
Go
Raw Normal View History

2024-05-07 13:33:51 +00:00
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
}
2024-05-07 13:46:06 +00:00
imageurl := "https://images.weserv.nl/?url="
2024-05-07 13:33:51 +00:00
info := &VideoInfo{
Owner: video.Data.Owner.Name,
2024-05-07 13:46:06 +00:00
Face: imageurl + video.Data.Owner.Face,
2024-05-07 13:33:51 +00:00
Title: video.Data.Title,
Desc: video.Data.Desc,
Duration: secondsToTimeString(video.Data.Duration),
2024-05-07 13:46:06 +00:00
Pic: imageurl + video.Data.Pic,
2024-05-07 13:33:51 +00:00
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")
err = json.NewEncoder(w).Encode(info)
if err != nil {
http.Error(w, "无法解析视频数据", http.StatusInternalServerError)
}
}
2024-05-22 08:30:01 +00:00
func BilibiliInit() {
http.HandleFunc("/api/bilibili", GetVideoData)
}