package main import ( "bufio" "bytes" "encoding/json" "fmt" "log" "os" "os/exec" "strings" "net/http" "net/url" ) var version = "1.0.1" func help () { fmt.Println("076 rofi-youtube") fmt.Println("https://076.moe/ | https://gitler.moe/suwako/rofi-youtube") fmt.Println("") fmt.Println("使い方") fmt.Println("rofi-youtube -i :動画IDを使ってMPVで再生する") fmt.Println("rofi-youtube -v :バージョンを表示") fmt.Println("rofi-youtube -s :動画を検索して、再生する") fmt.Println("rofi-youtube -h :ヘルプを表示") } type Video struct { Type string `json:"type"` Title string `json:"title"` VideoID string `json:"videoId"` Author string `json:"author"` AuthorID string `json:"authorId"` AuthorURL string `json:"authorUrl"` VideoThumbnails []struct { Quality string `json:"quality"` URL string `json:"url"` Width int `json:"width"` Height int `json:"height"` } `json:"videoThumbnails"` Description string `json:"description"` DescriptionHTML string `json:"descriptionHtml"` ViewCount int `json:"viewCount"` Published int64 `json:"published"` PublishedText string `json:"publishedText"` LengthSeconds int `json:"lengthSeconds"` LiveNow bool `json:"liveNow"` Paid bool `json:"paid"` Premium bool `json:"premium"` } func id () { vid := rofi("動画IDを入力して下さい", nil) if vid != "" { if strings.Contains(vid, "watch?v=") { vid = strings.Split(vid, "=")[1] } url := fmt.Sprintf("https://www.youtube.com/watch?v=%s", vid) cmd := exec.Command("mpv", url) err := cmd.Start() if err != nil { log.Fatalf("失敗: %v", err) } } } func search () { q := rofi("動画を検索して下さい", nil) vids := fetch(q) var tits []string for _, v := range vids { tits = append(tits, v.Title) } stit := rofi("動画を選択して下さい", tits) var vid *Video for _, v := range vids { if v.Title == stit { vid = &v break } } if vid != nil { url := fmt.Sprintf("https://www.youtube.com/watch?v=%s", vid.VideoID) cmd := exec.Command("mpv", url) err := cmd.Start() if err != nil { log.Fatalf("失敗: %v", err) } } return } func rofi (prompt string, options []string) string { cmd := exec.Command("rofi", "-dmenu", "-p", prompt) var out bytes.Buffer cmd.Stdout = &out if options != nil { cmd.Stdin = strings.NewReader(strings.Join(options, "\n")) } err := cmd.Run() if err != nil { log.Fatalf("rofiを実行に失敗: %v", err) } return strings.TrimSpace(out.String()) } func fetch (q string) []Video { url := fmt.Sprintf("https://youtube.owacon.moe/api/v1/search?q=%s&page=1&type=video®ion=JP", url.QueryEscape(q)) resp, err := http.Get(url) if err != nil { log.Fatalf("検索に失敗: %v", err) } defer resp.Body.Close() var vres []Video dec := json.NewDecoder(bufio.NewReader(resp.Body)) err = dec.Decode(&vres) if err != nil { log.Fatalf("デコードに失敗: %v", err) } return vres } func main () { args := os.Args if len(args) == 2 { if args[1] == "-i" { id() return } else if args[1] == "-v" { fmt.Println("rofi-youtube-" + version) return } else if args[1] == "-s" { search() return } else if args[1] == "-h" { help() return } } help() return }