227 lines
7.4 KiB
Go
227 lines
7.4 KiB
Go
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")
|
||
err = json.NewEncoder(w).Encode(info)
|
||
if err != nil {
|
||
http.Error(w, "无法解析视频数据", http.StatusInternalServerError)
|
||
}
|
||
}
|