2023-06-10 12:21:46 +09:00
|
|
|
|
package main
|
|
|
|
|
|
|
|
|
|
import (
|
2023-06-10 19:43:32 +09:00
|
|
|
|
"bufio"
|
|
|
|
|
"bytes"
|
|
|
|
|
"encoding/json"
|
|
|
|
|
"fmt"
|
|
|
|
|
"log"
|
2023-06-10 12:21:46 +09:00
|
|
|
|
"os"
|
2023-06-10 19:43:32 +09:00
|
|
|
|
"os/exec"
|
|
|
|
|
"strings"
|
2023-06-10 12:21:46 +09:00
|
|
|
|
|
2023-06-10 19:43:32 +09:00
|
|
|
|
"net/http"
|
|
|
|
|
"net/url"
|
2023-06-10 12:21:46 +09:00
|
|
|
|
)
|
|
|
|
|
|
2023-06-10 20:06:01 +09:00
|
|
|
|
var version = "1.0.1"
|
2023-06-10 12:21:46 +09:00
|
|
|
|
|
|
|
|
|
func help () {
|
2023-12-08 12:40:20 +09:00
|
|
|
|
fmt.Println("076 rofi-youtube")
|
|
|
|
|
fmt.Println("https://076.moe/ | https://gitler.moe/suwako/rofi-youtube")
|
|
|
|
|
fmt.Println("")
|
2023-06-10 12:21:46 +09:00
|
|
|
|
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 {
|
2023-06-10 19:43:32 +09:00
|
|
|
|
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"`
|
2023-06-10 12:21:46 +09:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func id () {
|
2023-06-10 19:43:32 +09:00
|
|
|
|
vid := rofi("動画IDを入力して下さい", nil)
|
2023-06-10 12:21:46 +09:00
|
|
|
|
|
2023-06-10 19:43:32 +09:00
|
|
|
|
if vid != "" {
|
2023-06-10 12:21:46 +09:00
|
|
|
|
if strings.Contains(vid, "watch?v=") {
|
|
|
|
|
vid = strings.Split(vid, "=")[1]
|
|
|
|
|
}
|
2023-06-10 19:43:32 +09:00
|
|
|
|
url := fmt.Sprintf("https://www.youtube.com/watch?v=%s", vid)
|
2023-06-10 12:21:46 +09:00
|
|
|
|
cmd := exec.Command("mpv", url)
|
2023-06-10 19:43:32 +09:00
|
|
|
|
err := cmd.Start()
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Fatalf("失敗: %v", err)
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-06-10 12:21:46 +09:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func search () {
|
|
|
|
|
q := rofi("動画を検索して下さい", nil)
|
|
|
|
|
|
2023-06-10 19:43:32 +09:00
|
|
|
|
vids := fetch(q)
|
2023-06-10 12:21:46 +09:00
|
|
|
|
|
2023-06-10 19:43:32 +09:00
|
|
|
|
var tits []string
|
|
|
|
|
for _, v := range vids {
|
|
|
|
|
tits = append(tits, v.Title)
|
|
|
|
|
}
|
2023-06-10 12:21:46 +09:00
|
|
|
|
|
2023-06-10 19:43:32 +09:00
|
|
|
|
stit := rofi("動画を選択して下さい", tits)
|
2023-06-10 12:21:46 +09:00
|
|
|
|
|
2023-06-10 19:43:32 +09:00
|
|
|
|
var vid *Video
|
|
|
|
|
for _, v := range vids {
|
|
|
|
|
if v.Title == stit {
|
|
|
|
|
vid = &v
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-06-10 12:21:46 +09:00
|
|
|
|
|
2023-06-10 19:43:32 +09:00
|
|
|
|
if vid != nil {
|
|
|
|
|
url := fmt.Sprintf("https://www.youtube.com/watch?v=%s", vid.VideoID)
|
2023-06-10 12:21:46 +09:00
|
|
|
|
cmd := exec.Command("mpv", url)
|
2023-06-10 19:43:32 +09:00
|
|
|
|
err := cmd.Start()
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Fatalf("失敗: %v", err)
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-06-10 12:21:46 +09:00
|
|
|
|
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func rofi (prompt string, options []string) string {
|
2023-06-10 19:43:32 +09:00
|
|
|
|
cmd := exec.Command("rofi", "-dmenu", "-p", prompt)
|
2023-06-10 12:21:46 +09:00
|
|
|
|
|
2023-06-10 19:43:32 +09:00
|
|
|
|
var out bytes.Buffer
|
|
|
|
|
cmd.Stdout = &out
|
2023-06-10 12:21:46 +09:00
|
|
|
|
|
2023-06-10 19:43:32 +09:00
|
|
|
|
if options != nil {
|
|
|
|
|
cmd.Stdin = strings.NewReader(strings.Join(options, "\n"))
|
|
|
|
|
}
|
2023-06-10 12:21:46 +09:00
|
|
|
|
|
2023-06-10 19:43:32 +09:00
|
|
|
|
err := cmd.Run()
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Fatalf("rofiを実行に失敗: %v", err)
|
|
|
|
|
}
|
2023-06-10 12:21:46 +09:00
|
|
|
|
|
2023-06-10 19:43:32 +09:00
|
|
|
|
return strings.TrimSpace(out.String())
|
2023-06-10 12:21:46 +09:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func fetch (q string) []Video {
|
2023-06-10 19:43:32 +09:00
|
|
|
|
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
|
2023-06-10 12:21:46 +09:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
}
|