Skip to content

Commit

Permalink
first commit
Browse files Browse the repository at this point in the history
  • Loading branch information
ankikong committed Oct 3, 2019
0 parents commit 2200ba4
Show file tree
Hide file tree
Showing 13 changed files with 807 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.vscode/*
*.exe
bin/*
Binary file added README.md
Binary file not shown.
41 changes: 41 additions & 0 deletions download.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package main

import (
"log"
"net/http"
"os"
"strings"
)

func Download(url, name, path string) error {
path = strings.TrimSpace(path)
if len(path) == 0 {
path = "./"
} else if path[len(path)-1] != '/' {
path = path + "/"
}
tmp := strings.Split(url, ".")
ext := tmp[len(tmp)-1]
name = name + "." + ext
rs, err := http.Get(url)
if err != nil {
log.Println("download fail:", err.Error())
return err
}
file, err := os.Create(path + name)
if err != nil {
log.Println("create file fail:", err.Error())
return err
}
buf := make([]byte, 262144)
for {
len, err := rs.Body.Read(buf)
file.Write(buf[:len])
if err != nil {
break
}
}
file.Close()
rs.Body.Close()
return nil
}
100 changes: 100 additions & 0 deletions kugou/api.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
package kugou

import (
"crypto/md5"
"encoding/hex"
"encoding/json"
"log"
"net/http"

"github.com/ankikong/goMusic/songBean"
)

type kugouSongUrl struct {
SongBr int `json:"bitRate"`
SongSize int `json:"fileSize"`
Urls []string `json:"url"`
SongName string `json:"fileName"`
}

type kugouSearchPerResult struct {
HQHash string `json:"HQFileHash"`
HQSize int `json:"HQFileSize"`
SQHash string `json:"SQFileHash"`
SQSize int `json:"SQFileSize"`
FileName string `json:"FileName"`
ArtistName string `json:"SingerName"`
AlbumName string `json:"AlbumName"`
}

func (kg kugouSearchPerResult) GetFileName() string {
return kg.FileName
}

func (kg kugouSearchPerResult) GetArtistName() string {
return kg.ArtistName
}

func (kg kugouSearchPerResult) GetAlbumName() string {
return kg.AlbumName
}

func (kg kugouSearchPerResult) GetUrl(br int) songBean.SongInfo {
if br == 990 && kg.SQHash != "" {
return GetSongUrl([]string{kg.SQHash})[0]
} else {
return GetSongUrl([]string{kg.HQHash})[0]
}
}

type kugouData struct {
List []kugouSearchPerResult `json:"lists"`
}
type kugouSearchResult struct {
Data kugouData
}

func MD5(text string) string {
data := []byte(text)
hash := md5.Sum(data)
return hex.EncodeToString(hash[:])
}

func doGet(url string) []byte {
rs, err := http.Get(url)
if err != nil {
log.Println(err)
return nil
}
defer rs.Body.Close()
tmpBuf := make([]byte, 65536)
len, _ := rs.Body.Read(tmpBuf)
return tmpBuf[:len]
}

func GetSongUrl(ids []string) []songBean.SongInfo {
ansRet := make([]songBean.SongInfo, len(ids))
index := 0
for _, id := range ids {
tmpHash := MD5(id + "kgcloudv2")
api := `http://trackercdn.kugou.com/i/v2/?key=` + tmpHash + `&hash=` + id + `&br=hq&appid=1005&pid=2&cmd=25&behavior=play`
tmpBuf := doGet(api)
var song kugouSongUrl
json.Unmarshal(tmpBuf, &song)
ansRet[index].SongBr = song.SongBr
ansRet[index].SongName = song.SongName
ansRet[index].SongSize = song.SongSize
ansRet[index].SongUrl = song.Urls[0]
index++
}
return ansRet
}

func Search(word string) []kugouSearchPerResult {
Url := `http://songsearch.kugou.com/song_search_v2?pagesize=5&keyword=` + word
rs := doGet(Url)
// fmt.Println(string(rs))
var ans kugouSearchResult
json.Unmarshal(rs, &ans)
return ans.Data.List
}
21 changes: 21 additions & 0 deletions kugou/api_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package kugou

import (
"fmt"
"testing"

"github.com/ankikong/goMusic/songBean"
)

func TestGetSongUrl(t *testing.T) {
rs := GetSongUrl([]string{"4D870D0DEB13AA6700BEECA513C6B03C", "40AD169093CDE5523A13DA8E7A09066B"})
fmt.Println(rs)
}

func TestSearch(t *testing.T) {
rs := Search("claris")
fmt.Println(rs)
rs[0].GetUrl(320)
var val songBean.SongUrl = rs[0]
fmt.Println(val.GetUrl(320))
}
91 changes: 91 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package main

import (
"flag"
"fmt"
"os"
"regexp"
"strconv"
"strings"

"github.com/ankikong/goMusic/kugou"
"github.com/ankikong/goMusic/songBean"

"github.com/ankikong/goMusic/netease"
"github.com/jedib0t/go-pretty/table"
)

func search(text string) {
var result []songBean.SongData
for _, rs := range netease.Search(text) {
result = append(result, rs)
}
for _, rs := range kugou.Search(text) {
result = append(result, rs)
}
t := table.NewWriter()
t.SetOutputMirror(os.Stdout)
t.AppendHeader(table.Row{"编号", "歌名", "歌手", "专辑"})
// fmt.Println("歌名\t歌手\t专辑")
// fmt.Printf("%-26s%-26s%-26s\n", "歌名", "歌手", "专辑")
index := 0
for _, rs := range result {
t.AppendRow(table.Row{index, rs.GetFileName(), rs.GetArtistName(), rs.GetAlbumName()})
index++
// fmt.Printf("%-26s%-26s%-26s\n", rs.GetFileName(), rs.GetArtistName(), rs.GetAlbumName())
}
var input string
var num uint64
// stdin := bufio.NewReader(os.Stdin)
t.Render()
for {
fmt.Print("please input integer(input q to quit):")
// fmt.Println(input)
fmt.Scan(&input)
// fmt.Fscan(stdin, input)
input = strings.TrimSpace(input)
input = strings.ToLower(input)
if input == "q" {
return
}
nums, err := strconv.ParseUint(input, 10, 20)
if err != nil {
continue
}
num = nums
break
}
rss := result[num].GetUrl(320)
fmt.Println(rss.SongUrl)
Download(rss.SongUrl, rss.SongName, "")
}

func GetByNeteaseId(url string) {
reg, _ := regexp.Compile(`\Wid=\d+`)
ids := reg.FindAllString(url, -1)
if len(ids) == 0 {
fmt.Println("输入错误")
return
}
id := ids[0][4:]
rs := netease.GetSongUrl([]string{fmt.Sprint(id)}, 320)[0]
fmt.Println("开始下载:", rs.SongName)
Download(rs.SongUrl, rs.SongName, "")
}

func main() {
var (
url string
keyword string
)
flag.StringVar(&url, "url", "", "url of song")
flag.StringVar(&keyword, "kw", "", "search keyword")
flag.Parse()
if len(keyword) > 0 {
search(keyword)
} else {
if strings.Contains(url, "music.163.com") {
GetByNeteaseId(url)
}
}
}
61 changes: 61 additions & 0 deletions makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# Go parameters
GOCMD=go
GOBUILD=$(GOCMD) build
GOCLEAN=$(GOCMD) clean
GOTEST=$(GOCMD) test
GOGET=$(GOCMD) get

RELEASE_VERSION=V0.0.1
BINARY_NAME=goMusic-$(RELEASE_VERSION)
BINARY_DIR=bin


all: test build
build:
$(GOBUILD) -o $(BINARY_DIR)/$(BINARY_NAME).exe -v
test:
$(GOTEST) -v ./...
clean:
$(GOCLEAN)
rm -f $(BINARY_NAME)
rm -f $(BINARY_UNIX)
run:
$(GOBUILD) -o $(BINARY_NAME) -v ./...
./$(BINARY_NAME)

deps:
$(GOGET) github.com/jedib0t/go-pretty/table

# Cross compilation

# windows
build-win64:
CGO_ENABLED=0 GOOS=windows GOARCH=amd64 $(GOBUILD) -o $(BINARY_DIR)/$(BINARY_NAME)_win64.exe -v
build-win32:
CGO_ENABLED=0 GOOS=windows GOARCH=386 $(GOBUILD) -o $(BINARY_DIR)/$(BINARY_NAME)_win32.exe -v

# Linux
build-linux-amd64:
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 $(GOBUILD) -o $(BINARY_DIR)/$(BINARY_NAME)_linux_amd64 -v
build-linux-X86:
CGO_ENABLED=0 GOOS=linux GOARCH=386 $(GOBUILD) -o $(BINARY_DIR)/$(BINARY_NAME)_linux_X86 -v
build-linux-arm64:
CGO_ENABLED=0 GOOS=linux GOARCH=arm64 $(GOBUILD) -o $(BINARY_DIR)/$(BINARY_NAME)_linux_arm64 -v
build-linux-armV7:
CGO_ENABLED=0 GOOS=linux GOARCH=arm GOARM=7 $(GOBUILD) -o $(BINARY_DIR)/$(BINARY_NAME)_linux_armV7 -v

# Mac
build-darwin-X86:
CGO_ENABLED=0 GOOS=darwin GOARCH=386 $(GOBUILD) -o $(BINARY_DIR)/$(BINARY_NAME)_darwin_X86 -v
build-darwin-amd64:
CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 $(GOBUILD) -o $(BINARY_DIR)/$(BINARY_NAME)_darwin_amd64 -v

build-all:
make build-win64
make build-win32
make build-linux-amd64
make build-linux-X86
make build-linux-arm64
make build-linux-armV7
make build-darwin-X86
make build-darwin-amd64
Loading

0 comments on commit 2200ba4

Please sign in to comment.