Skip to content

Commit

Permalink
[feature]<main>: support random mode ✨✨ (#21)
Browse files Browse the repository at this point in the history
  • Loading branch information
o98k-ok authored Jul 4, 2024
1 parent c1fdac0 commit f3ebc4c
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 1 deletion.
27 changes: 27 additions & 0 deletions internal/bilibili/hot.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ type DouyinHot struct {

type DouyinHelper interface {
HotKeys() []string
Free() string
}

type Douyin struct {
Expand Down Expand Up @@ -52,3 +53,29 @@ func (dy *Douyin) HotKeys() []string {
}
return keys
}

type FreeResp struct {
Code int `json:"code"`
Data struct {
Name string `json:"name"`
URL string `json:"url"`
Picurl string `json:"picurl"`
Artistsname string `json:"artistsname"`
} `json:"data"`
}

func (dy *Douyin) Free() string {
rawURL := "https://api.uomg.com/api/rand.music?sort=飙升榜&format=json"

req := netutil.HttpRequest{
RawURL: rawURL,
Method: http.MethodGet,
Headers: make(http.Header),
QueryParams: make(url.Values),
}
resp, err := pkg.Request(dy.cli, &req, func(result *FreeResp) bool { return result.Code == 1 && len(result.Data.Name) > 0 })
if err != nil {
return ""
}
return resp.Data.Name
}
3 changes: 3 additions & 0 deletions internal/pkg/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package pkg
import (
"encoding/json"
"errors"
"fmt"
"net/http"

"github.com/duke-git/lancet/v2/netutil"
Expand All @@ -24,10 +25,12 @@ func Request[T any](cli *netutil.HttpClient, req *netutil.HttpRequest, validate
return nil, err
}
if response.StatusCode != http.StatusOK {
fmt.Println(response.StatusCode)
return nil, ErrHttpRequest
}

if !validate(&result) {
fmt.Println(result)
return nil, ErrHttpRequest
}
return &result, nil
Expand Down
34 changes: 33 additions & 1 deletion internal/player/play.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,10 @@ type VoicePlayer struct {
PlayingQueue *StreamerQueue

CurrentElem *list.Element
FreeElem *list.Element
ModeIdx int64
Modes []string
ForceNext bool
}

func NewVoicePlayer(sampleRate int64) *VoicePlayer {
Expand All @@ -48,11 +50,19 @@ func NewVoicePlayer(sampleRate int64) *VoicePlayer {
SampleRate: sampleRate,
PlayList: list.New(),
PlayingQueue: NewStreamerQueue(int(sampleRate)),
Modes: []string{"sequence", "cycle", "random"},
Modes: []string{"sequence", "cycle", "random", "free"},
ModeIdx: 0,
}
}

func (vp *VoicePlayer) WithFreeModeSong() bool {
return vp.FreeElem != nil
}

func (vp *VoicePlayer) SetFreeModeSong(song *music.Music) {
vp.FreeElem = &list.Element{Value: song}
}

func (vp *VoicePlayer) InitPlayList(storage storage.Storage) {
for m := range storage.HistoryMusics() {
vp.AddInQueue(&music.Music{
Expand All @@ -74,6 +84,8 @@ func (vp *VoicePlayer) GetMode() string {
return "🔄 循环"
case "random":
return "🔀 随机"
case "free":
return "🫶 自由"
default:
return "⏯ 顺序"
}
Expand Down Expand Up @@ -133,6 +145,7 @@ func (vp *VoicePlayer) NextP(p *list.Element) (*music.Music, error) {
ctrl := vp.Current()
vp.CurrentElem = p
if ctrl != nil && ctrl.NextTrigger != nil {
vp.ForceNext = true
ctrl.NextTrigger()
}
return nil, nil
Expand Down Expand Up @@ -162,7 +175,26 @@ func (vp *VoicePlayer) Run() error {
fn()
}
}

// 手动切换到下一首,忽略播放模式
if vp.ForceNext {
vp.CurrentElem = pkg.NextForward(vp.PlayList, vp.CurrentElem)
if vp.CurrentElem != nil {
vp.PlayingQueue.Add(vp.CurrentElem)
}
vp.ForceNext = false
continue
}

switch vp.Modes[vp.ModeIdx] {
case "free":
if vp.FreeElem != nil {
vp.CurrentElem = vp.PlayList.PushBack(vp.FreeElem.Value)
vp.FreeElem = nil
}
if vp.CurrentElem != nil {
vp.PlayingQueue.Add(vp.CurrentElem)
}
case "random":
vp.CurrentElem = pkg.NextN(vp.PlayList, vp.CurrentElem, random.RandInt(-10, 10))
if vp.CurrentElem != nil {
Expand Down
58 changes: 58 additions & 0 deletions internal/ui/input.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"
"os"
"strconv"
"time"

"github.com/charmbracelet/bubbles/textinput"
tea "github.com/charmbracelet/bubbletea"
Expand Down Expand Up @@ -62,6 +63,63 @@ func (ie *InputElem) Init() tea.Cmd {
keys := ie.dyHelper.HotKeys()
ie.suggestKeys = keys
ie.suggestKey = keys[0]

// 处理free mode播放场景
go func() {
for {
time.Sleep(time.Millisecond * 200)
if ie.player.Modes[ie.player.ModeIdx] == "free" && !ie.player.WithFreeModeSong() {
keyword := ie.dyHelper.Free()
if len(keyword) == 0 {
continue
}

// 搜索、下载、加入列表
musics, err := ie.fetcher.Search(keyword, 1, 5)
if err != nil || len(musics) == 0 {
continue
}

for i, u := range ie.fetcher.GetAudioURL(musics[0].BvID) {
func(bvID string, url string, idx int, mm *music.Music) {
root := ie.storage.GetRootPath()
namein := fmt.Sprintf("%s/%s_%d.mp4", root, bvID, idx)
nameout := fmt.Sprintf("%s/%s_%d.wav", root, bvID, idx)

fin, _ := os.Create(namein)
fout, _ := os.Create(nameout)
ie.fetcher.Download(url, fin)
fin.Close()

fin, _ = os.Open(namein)

ie.mconvertor.ConvertM4AToWav(fin, fout)
fin.Close()
fout.Close()
os.Remove(namein)

ie.storage.SaveMusic(music.MusicKey{
Name: mm.Name,
Desc: mm.Desc,
BVID: bvID,
LocalPath: nameout,
Duration: mm.Duration,
})

ms := music.Music{
Name: mm.Name,
Desc: mm.Desc,
URL: url,
BvID: bvID,
LocalPath: nameout,
Duration: mm.Duration,
}
ie.player.SetFreeModeSong(&ms)
}(musics[0].BvID, u, i, musics[0])
}
}
}
}()
return textinput.Blink
}

Expand Down

0 comments on commit f3ebc4c

Please sign in to comment.