init libmiaosic

This commit is contained in:
aynakeya
2025-12-29 21:46:23 +08:00
parent a77b4a564e
commit 8e1f6414b9
5 changed files with 1013 additions and 6 deletions

76
api.go
View File

@@ -64,3 +64,79 @@ func MatchMediaByProvider(provider string, uri string) (MetaData, bool) {
}
return p.MatchMedia(uri)
}
func loginableByProvider(provider string) (Loginable, error) {
p, ok := GetProvider(provider)
if !ok {
return nil, ErrorNoSuchProvider
}
loginable, ok := p.(Loginable)
if !ok {
return nil, ErrorProviderNotLoginable
}
return loginable, nil
}
func LoginByProvider(provider, username, password string) error {
loginable, err := loginableByProvider(provider)
if err != nil {
return err
}
return loginable.Login(username, password)
}
func LogoutByProvider(provider string) error {
loginable, err := loginableByProvider(provider)
if err != nil {
return err
}
return loginable.Logout()
}
func IsLoginByProvider(provider string) (bool, error) {
loginable, err := loginableByProvider(provider)
if err != nil {
return false, err
}
return loginable.IsLogin(), nil
}
func RefreshLoginByProvider(provider string) error {
loginable, err := loginableByProvider(provider)
if err != nil {
return err
}
return loginable.RefreshLogin()
}
func QrLoginByProvider(provider string) (*QrLoginSession, error) {
loginable, err := loginableByProvider(provider)
if err != nil {
return nil, err
}
return loginable.QrLogin()
}
func QrLoginVerifyByProvider(provider string, qrlogin *QrLoginSession) (*QrLoginResult, error) {
loginable, err := loginableByProvider(provider)
if err != nil {
return nil, err
}
return loginable.QrLoginVerify(qrlogin)
}
func RestoreSessionByProvider(provider, session string) error {
loginable, err := loginableByProvider(provider)
if err != nil {
return err
}
return loginable.RestoreSession(session)
}
func SaveSessionByProvider(provider string) (string, error) {
loginable, err := loginableByProvider(provider)
if err != nil {
return "", err
}
return loginable.SaveSession(), nil
}

View File

@@ -1 +0,0 @@
package libmiaosic

View File

@@ -5,9 +5,10 @@ import "errors"
var ErrNotImplemented = errors.New("miaosic: not implemented")
var (
ErrorExternalApi = errors.New("miaosic: external api error")
ErrorNoSuchProvider = errors.New("miaosic: no such provider")
ErrorDifferentProvider = errors.New("miaosic: different provider")
ErrorInvalidPageSetting = errors.New("miaosic: invalid page setting")
ErrorInvalidMediaMeta = errors.New("miaosic: invalid media meta")
ErrorExternalApi = errors.New("miaosic: external api error")
ErrorNoSuchProvider = errors.New("miaosic: no such provider")
ErrorProviderNotLoginable = errors.New("miaosic: provider not loginable")
ErrorDifferentProvider = errors.New("miaosic: different provider")
ErrorInvalidPageSetting = errors.New("miaosic: invalid page setting")
ErrorInvalidMediaMeta = errors.New("miaosic: invalid media meta")
)

779
libmiaosic/libmiaosic.go Normal file
View File

@@ -0,0 +1,779 @@
package main
/*
#include <stdlib.h>
#include <string.h>
#include "libmiaosic.h"
*/
import "C"
import (
"errors"
"unsafe"
"github.com/AynaLivePlayer/miaosic"
"github.com/AynaLivePlayer/miaosic/providers/bilivideo"
"github.com/AynaLivePlayer/miaosic/providers/kugou"
"github.com/AynaLivePlayer/miaosic/providers/kuwo"
"github.com/AynaLivePlayer/miaosic/providers/local"
"github.com/AynaLivePlayer/miaosic/providers/netease"
"github.com/AynaLivePlayer/miaosic/providers/qq"
)
func init() {
miaosic.UnregisterAllProvider()
}
func goString(val *C.char) string {
if val == nil {
return ""
}
return C.GoString(val)
}
func newResult(data unsafe.Pointer, resultType C.MiaosicResultType, err error) *C.MiaosicResult {
result := (*C.MiaosicResult)(C.malloc(C.size_t(unsafe.Sizeof(C.MiaosicResult{}))))
if result == nil {
return nil
}
result.ok = 0
result.err = nil
result.result_type = resultType
result.data = data
if err == nil {
result.ok = 1
return result
}
result.err = C.CString(err.Error())
return result
}
func newBoolResult(val bool) unsafe.Pointer {
ptr := (*C.MiaosicBool)(C.malloc(C.size_t(unsafe.Sizeof(C.MiaosicBool{}))))
if ptr == nil {
return nil
}
ptr.value = 0
if val {
ptr.value = 1
}
return unsafe.Pointer(ptr)
}
func newStringResult(val string) unsafe.Pointer {
ptr := (*C.MiaosicString)(C.malloc(C.size_t(unsafe.Sizeof(C.MiaosicString{}))))
if ptr == nil {
return nil
}
ptr.value = C.CString(val)
return unsafe.Pointer(ptr)
}
func fillMetaData(dst *C.MiaosicMetaData, meta miaosic.MetaData) {
dst.provider = C.CString(meta.Provider)
dst.identifier = C.CString(meta.Identifier)
}
func fillPicture(dst *C.MiaosicPicture, pic miaosic.Picture) {
dst.url = nil
dst.data = nil
dst.data_len = 0
if pic.Url != "" {
dst.url = C.CString(pic.Url)
}
if len(pic.Data) > 0 {
dst.data = (*C.uchar)(C.malloc(C.size_t(len(pic.Data))))
if dst.data != nil {
C.memcpy(unsafe.Pointer(dst.data), unsafe.Pointer(&pic.Data[0]), C.size_t(len(pic.Data)))
dst.data_len = C.int(len(pic.Data))
}
}
}
func fillMediaInfo(dst *C.MiaosicMediaInfo, info miaosic.MediaInfo) {
dst.title = C.CString(info.Title)
dst.artist = C.CString(info.Artist)
dst.album = C.CString(info.Album)
fillPicture(&dst.cover, info.Cover)
fillMetaData(&dst.meta, info.Meta)
}
func newMediaInfoResult(info miaosic.MediaInfo) unsafe.Pointer {
ptr := (*C.MiaosicMediaInfo)(C.malloc(C.size_t(unsafe.Sizeof(C.MiaosicMediaInfo{}))))
if ptr == nil {
return nil
}
fillMediaInfo(ptr, info)
return unsafe.Pointer(ptr)
}
func newMediaInfoListResult(items []miaosic.MediaInfo) unsafe.Pointer {
list := (*C.MiaosicMediaInfoList)(C.malloc(C.size_t(unsafe.Sizeof(C.MiaosicMediaInfoList{}))))
if list == nil {
return nil
}
list.len = C.int(len(items))
list.items = nil
if len(items) == 0 {
return unsafe.Pointer(list)
}
list.items = (*C.MiaosicMediaInfo)(C.malloc(C.size_t(len(items)) * C.size_t(unsafe.Sizeof(C.MiaosicMediaInfo{}))))
if list.items == nil {
list.len = 0
return unsafe.Pointer(list)
}
slice := (*[1 << 30]C.MiaosicMediaInfo)(unsafe.Pointer(list.items))[:len(items):len(items)]
for i, item := range items {
fillMediaInfo(&slice[i], item)
}
return unsafe.Pointer(list)
}
func fillHeaderPairs(headers map[string]string) (*C.MiaosicHeaderPair, C.int) {
if len(headers) == 0 {
return nil, 0
}
ptr := (*C.MiaosicHeaderPair)(C.malloc(C.size_t(len(headers)) * C.size_t(unsafe.Sizeof(C.MiaosicHeaderPair{}))))
if ptr == nil {
return nil, 0
}
slice := (*[1 << 30]C.MiaosicHeaderPair)(unsafe.Pointer(ptr))[:len(headers):len(headers)]
idx := 0
for key, value := range headers {
slice[idx].key = C.CString(key)
slice[idx].value = C.CString(value)
idx++
}
return ptr, C.int(len(headers))
}
func fillMediaUrl(dst *C.MiaosicMediaUrl, url miaosic.MediaUrl) {
dst.url = C.CString(url.Url)
dst.quality = C.CString(string(url.Quality))
dst.headers = nil
dst.header_len = 0
headers, headerLen := fillHeaderPairs(url.Header)
dst.headers = headers
dst.header_len = headerLen
}
func newMediaUrlListResult(items []miaosic.MediaUrl) unsafe.Pointer {
list := (*C.MiaosicMediaUrlList)(C.malloc(C.size_t(unsafe.Sizeof(C.MiaosicMediaUrlList{}))))
if list == nil {
return nil
}
list.len = C.int(len(items))
list.items = nil
if len(items) == 0 {
return unsafe.Pointer(list)
}
list.items = (*C.MiaosicMediaUrl)(C.malloc(C.size_t(len(items)) * C.size_t(unsafe.Sizeof(C.MiaosicMediaUrl{}))))
if list.items == nil {
list.len = 0
return unsafe.Pointer(list)
}
slice := (*[1 << 30]C.MiaosicMediaUrl)(unsafe.Pointer(list.items))[:len(items):len(items)]
for i, item := range items {
fillMediaUrl(&slice[i], item)
}
return unsafe.Pointer(list)
}
func newPlaylistResult(playlist *miaosic.Playlist) unsafe.Pointer {
if playlist == nil {
return nil
}
ptr := (*C.MiaosicPlaylist)(C.malloc(C.size_t(unsafe.Sizeof(C.MiaosicPlaylist{}))))
if ptr == nil {
return nil
}
ptr.title = C.CString(playlist.Title)
fillMetaData(&ptr.meta, playlist.Meta)
medias := make([]miaosic.MediaInfo, len(playlist.Medias))
copy(medias, playlist.Medias)
listPtr := newMediaInfoListResult(medias)
if listPtr != nil {
ptr.medias = *(*C.MiaosicMediaInfoList)(listPtr)
C.free(listPtr)
} else {
ptr.medias.len = 0
ptr.medias.items = nil
}
return unsafe.Pointer(ptr)
}
func newMatchResult(meta miaosic.MetaData, matched bool) unsafe.Pointer {
ptr := (*C.MiaosicMatchResult)(C.malloc(C.size_t(unsafe.Sizeof(C.MiaosicMatchResult{}))))
if ptr == nil {
return nil
}
ptr.matched = 0
if matched {
ptr.matched = 1
}
fillMetaData(&ptr.meta, meta)
return unsafe.Pointer(ptr)
}
func newQrLoginSessionResult(session *miaosic.QrLoginSession) unsafe.Pointer {
if session == nil {
return nil
}
ptr := (*C.MiaosicQrLoginSession)(C.malloc(C.size_t(unsafe.Sizeof(C.MiaosicQrLoginSession{}))))
if ptr == nil {
return nil
}
ptr.url = C.CString(session.Url)
ptr.key = C.CString(session.Key)
return unsafe.Pointer(ptr)
}
func newQrLoginResult(res *miaosic.QrLoginResult) unsafe.Pointer {
if res == nil {
return nil
}
ptr := (*C.MiaosicQrLoginResult)(C.malloc(C.size_t(unsafe.Sizeof(C.MiaosicQrLoginResult{}))))
if ptr == nil {
return nil
}
ptr.success = 0
if res.Success {
ptr.success = 1
}
ptr.message = C.CString(res.Message)
return unsafe.Pointer(ptr)
}
func newLyricsListResult(items []miaosic.Lyrics) unsafe.Pointer {
list := (*C.MiaosicLyricsList)(C.malloc(C.size_t(unsafe.Sizeof(C.MiaosicLyricsList{}))))
if list == nil {
return nil
}
list.len = C.int(len(items))
list.items = nil
if len(items) == 0 {
return unsafe.Pointer(list)
}
list.items = (*C.MiaosicLyrics)(C.malloc(C.size_t(len(items)) * C.size_t(unsafe.Sizeof(C.MiaosicLyrics{}))))
if list.items == nil {
list.len = 0
return unsafe.Pointer(list)
}
slice := (*[1 << 30]C.MiaosicLyrics)(unsafe.Pointer(list.items))[:len(items):len(items)]
for i, item := range items {
slice[i].lang = C.CString(item.Lang)
slice[i].lyrics = C.CString(item.String())
}
return unsafe.Pointer(list)
}
func newStringListResult(items []string) unsafe.Pointer {
list := (*C.MiaosicStringList)(C.malloc(C.size_t(unsafe.Sizeof(C.MiaosicStringList{}))))
if list == nil {
return nil
}
list.len = C.int(len(items))
list.items = nil
if len(items) == 0 {
return unsafe.Pointer(list)
}
list.items = (**C.char)(C.malloc(C.size_t(len(items)) * C.size_t(unsafe.Sizeof((*C.char)(nil)))))
if list.items == nil {
list.len = 0
return unsafe.Pointer(list)
}
slice := (*[1 << 30]*C.char)(unsafe.Pointer(list.items))[:len(items):len(items)]
for i, item := range items {
slice[i] = C.CString(item)
}
return unsafe.Pointer(list)
}
func registerProviderIfNeeded(provider miaosic.MediaProvider) error {
if provider == nil {
return errors.New("miaosic: provider is nil")
}
if _, ok := miaosic.GetProvider(provider.GetName()); ok {
return nil
}
miaosic.RegisterProvider(provider)
return nil
}
func freeMetaData(meta *C.MiaosicMetaData) {
if meta == nil {
return
}
if meta.provider != nil {
C.free(unsafe.Pointer(meta.provider))
}
if meta.identifier != nil {
C.free(unsafe.Pointer(meta.identifier))
}
}
func freePicture(pic *C.MiaosicPicture) {
if pic == nil {
return
}
if pic.url != nil {
C.free(unsafe.Pointer(pic.url))
}
if pic.data != nil {
C.free(unsafe.Pointer(pic.data))
}
}
func freeMediaInfo(info *C.MiaosicMediaInfo) {
if info == nil {
return
}
if info.title != nil {
C.free(unsafe.Pointer(info.title))
}
if info.artist != nil {
C.free(unsafe.Pointer(info.artist))
}
if info.album != nil {
C.free(unsafe.Pointer(info.album))
}
freePicture(&info.cover)
freeMetaData(&info.meta)
}
func freeHeaderPairs(headers *C.MiaosicHeaderPair, length C.int) {
if headers == nil || length == 0 {
return
}
slice := (*[1 << 30]C.MiaosicHeaderPair)(unsafe.Pointer(headers))[:length:length]
for i := 0; i < int(length); i++ {
if slice[i].key != nil {
C.free(unsafe.Pointer(slice[i].key))
}
if slice[i].value != nil {
C.free(unsafe.Pointer(slice[i].value))
}
}
C.free(unsafe.Pointer(headers))
}
func freeMediaUrl(url *C.MiaosicMediaUrl) {
if url == nil {
return
}
if url.url != nil {
C.free(unsafe.Pointer(url.url))
}
if url.quality != nil {
C.free(unsafe.Pointer(url.quality))
}
freeHeaderPairs(url.headers, url.header_len)
}
func freeMediaInfoList(list *C.MiaosicMediaInfoList) {
if list == nil {
return
}
if list.items != nil && list.len > 0 {
slice := (*[1 << 30]C.MiaosicMediaInfo)(unsafe.Pointer(list.items))[:list.len:list.len]
for i := 0; i < int(list.len); i++ {
freeMediaInfo(&slice[i])
}
C.free(unsafe.Pointer(list.items))
}
}
func freeMediaUrlList(list *C.MiaosicMediaUrlList) {
if list == nil {
return
}
if list.items != nil && list.len > 0 {
slice := (*[1 << 30]C.MiaosicMediaUrl)(unsafe.Pointer(list.items))[:list.len:list.len]
for i := 0; i < int(list.len); i++ {
freeMediaUrl(&slice[i])
}
C.free(unsafe.Pointer(list.items))
}
}
func freePlaylist(playlist *C.MiaosicPlaylist) {
if playlist == nil {
return
}
if playlist.title != nil {
C.free(unsafe.Pointer(playlist.title))
}
freeMetaData(&playlist.meta)
freeMediaInfoList(&playlist.medias)
}
func freeMatchResult(result *C.MiaosicMatchResult) {
if result == nil {
return
}
freeMetaData(&result.meta)
}
func freeQrLoginSession(session *C.MiaosicQrLoginSession) {
if session == nil {
return
}
if session.url != nil {
C.free(unsafe.Pointer(session.url))
}
if session.key != nil {
C.free(unsafe.Pointer(session.key))
}
}
func freeQrLoginResult(result *C.MiaosicQrLoginResult) {
if result == nil {
return
}
if result.message != nil {
C.free(unsafe.Pointer(result.message))
}
}
func freeLyricsList(list *C.MiaosicLyricsList) {
if list == nil {
return
}
if list.items != nil && list.len > 0 {
slice := (*[1 << 30]C.MiaosicLyrics)(unsafe.Pointer(list.items))[:list.len:list.len]
for i := 0; i < int(list.len); i++ {
if slice[i].lang != nil {
C.free(unsafe.Pointer(slice[i].lang))
}
if slice[i].lyrics != nil {
C.free(unsafe.Pointer(slice[i].lyrics))
}
}
C.free(unsafe.Pointer(list.items))
}
}
func freeStringList(list *C.MiaosicStringList) {
if list == nil {
return
}
if list.items != nil && list.len > 0 {
slice := (*[1 << 30]*C.char)(unsafe.Pointer(list.items))[:list.len:list.len]
for i := 0; i < int(list.len); i++ {
if slice[i] != nil {
C.free(unsafe.Pointer(slice[i]))
}
}
C.free(unsafe.Pointer(list.items))
}
}
//export FreeResult
func FreeResult(res *C.MiaosicResult) {
if res == nil {
return
}
if res.err != nil {
C.free(unsafe.Pointer(res.err))
}
if res.data != nil {
switch res.result_type {
case C.MIAOSIC_RESULT_BOOL:
C.free(res.data)
case C.MIAOSIC_RESULT_STRING:
str := (*C.MiaosicString)(res.data)
if str.value != nil {
C.free(unsafe.Pointer(str.value))
}
C.free(res.data)
case C.MIAOSIC_RESULT_STRING_LIST:
list := (*C.MiaosicStringList)(res.data)
freeStringList(list)
C.free(res.data)
case C.MIAOSIC_RESULT_META:
meta := (*C.MiaosicMetaData)(res.data)
freeMetaData(meta)
C.free(res.data)
case C.MIAOSIC_RESULT_MEDIA_INFO:
info := (*C.MiaosicMediaInfo)(res.data)
freeMediaInfo(info)
C.free(res.data)
case C.MIAOSIC_RESULT_MEDIA_INFO_LIST:
list := (*C.MiaosicMediaInfoList)(res.data)
freeMediaInfoList(list)
C.free(res.data)
case C.MIAOSIC_RESULT_MEDIA_URL_LIST:
list := (*C.MiaosicMediaUrlList)(res.data)
freeMediaUrlList(list)
C.free(res.data)
case C.MIAOSIC_RESULT_PLAYLIST:
playlist := (*C.MiaosicPlaylist)(res.data)
freePlaylist(playlist)
C.free(res.data)
case C.MIAOSIC_RESULT_MATCH:
match := (*C.MiaosicMatchResult)(res.data)
freeMatchResult(match)
C.free(res.data)
case C.MIAOSIC_RESULT_QR_LOGIN_SESSION:
session := (*C.MiaosicQrLoginSession)(res.data)
freeQrLoginSession(session)
C.free(res.data)
case C.MIAOSIC_RESULT_QR_LOGIN_RESULT:
result := (*C.MiaosicQrLoginResult)(res.data)
freeQrLoginResult(result)
C.free(res.data)
case C.MIAOSIC_RESULT_LYRICS_LIST:
list := (*C.MiaosicLyricsList)(res.data)
freeLyricsList(list)
C.free(res.data)
default:
C.free(res.data)
}
}
C.free(unsafe.Pointer(res))
}
//export SearchByProvider
func SearchByProvider(provider *C.char, keyword *C.char, page C.int, size C.int) *C.MiaosicResult {
data, err := miaosic.SearchByProvider(goString(provider), goString(keyword), int(page), int(size))
if err != nil {
return newResult(nil, C.MIAOSIC_RESULT_MEDIA_INFO_LIST, err)
}
resultData := newMediaInfoListResult(data)
return newResult(resultData, C.MIAOSIC_RESULT_MEDIA_INFO_LIST, err)
}
//export GetMediaUrl
func GetMediaUrl(provider *C.char, identifier *C.char, quality *C.char) *C.MiaosicResult {
meta := miaosic.NewMetaData(goString(provider), goString(identifier))
data, err := miaosic.GetMediaUrl(meta, miaosic.Quality(goString(quality)))
if err != nil {
return newResult(nil, C.MIAOSIC_RESULT_MEDIA_URL_LIST, err)
}
resultData := newMediaUrlListResult(data)
return newResult(resultData, C.MIAOSIC_RESULT_MEDIA_URL_LIST, err)
}
//export GetMediaInfo
func GetMediaInfo(provider *C.char, identifier *C.char) *C.MiaosicResult {
meta := miaosic.NewMetaData(goString(provider), goString(identifier))
data, err := miaosic.GetMediaInfo(meta)
if err != nil {
return newResult(nil, C.MIAOSIC_RESULT_MEDIA_INFO, err)
}
resultData := newMediaInfoResult(data)
return newResult(resultData, C.MIAOSIC_RESULT_MEDIA_INFO, err)
}
//export GetMediaLyric
func GetMediaLyric(provider *C.char, identifier *C.char) *C.MiaosicResult {
meta := miaosic.NewMetaData(goString(provider), goString(identifier))
data, err := miaosic.GetMediaLyric(meta)
if err != nil {
return newResult(nil, C.MIAOSIC_RESULT_LYRICS_LIST, err)
}
resultData := newLyricsListResult(data)
return newResult(resultData, C.MIAOSIC_RESULT_LYRICS_LIST, err)
}
//export MatchPlaylistByProvider
func MatchPlaylistByProvider(provider *C.char, uri *C.char) *C.MiaosicResult {
meta, matched := miaosic.MatchPlaylistByProvider(goString(provider), goString(uri))
resultData := newMatchResult(meta, matched)
return newResult(resultData, C.MIAOSIC_RESULT_MATCH, nil)
}
//export GetPlaylist
func GetPlaylist(provider *C.char, identifier *C.char) *C.MiaosicResult {
meta := miaosic.NewMetaData(goString(provider), goString(identifier))
data, err := miaosic.GetPlaylist(meta)
if err != nil {
return newResult(nil, C.MIAOSIC_RESULT_PLAYLIST, err)
}
resultData := newPlaylistResult(data)
return newResult(resultData, C.MIAOSIC_RESULT_PLAYLIST, err)
}
//export MatchMedia
func MatchMedia(keyword *C.char) *C.MiaosicResult {
meta, matched := miaosic.MatchMedia(goString(keyword))
resultData := newMatchResult(meta, matched)
return newResult(resultData, C.MIAOSIC_RESULT_MATCH, nil)
}
//export MatchMediaByProvider
func MatchMediaByProvider(provider *C.char, uri *C.char) *C.MiaosicResult {
meta, matched := miaosic.MatchMediaByProvider(goString(provider), goString(uri))
resultData := newMatchResult(meta, matched)
return newResult(resultData, C.MIAOSIC_RESULT_MATCH, nil)
}
//export ListAvailableProviders
func ListAvailableProviders() *C.MiaosicResult {
data := miaosic.ListAvailableProviders()
resultData := newStringListResult(data)
return newResult(resultData, C.MIAOSIC_RESULT_STRING_LIST, nil)
}
//export LoginByProvider
func LoginByProvider(provider *C.char, username *C.char, password *C.char) *C.MiaosicResult {
err := miaosic.LoginByProvider(goString(provider), goString(username), goString(password))
if err != nil {
return newResult(nil, C.MIAOSIC_RESULT_BOOL, err)
}
resultData := newBoolResult(true)
return newResult(resultData, C.MIAOSIC_RESULT_BOOL, nil)
}
//export LogoutByProvider
func LogoutByProvider(provider *C.char) *C.MiaosicResult {
err := miaosic.LogoutByProvider(goString(provider))
if err != nil {
return newResult(nil, C.MIAOSIC_RESULT_BOOL, err)
}
resultData := newBoolResult(true)
return newResult(resultData, C.MIAOSIC_RESULT_BOOL, nil)
}
//export IsLoginByProvider
func IsLoginByProvider(provider *C.char) *C.MiaosicResult {
data, err := miaosic.IsLoginByProvider(goString(provider))
if err != nil {
return newResult(nil, C.MIAOSIC_RESULT_BOOL, err)
}
resultData := newBoolResult(data)
return newResult(resultData, C.MIAOSIC_RESULT_BOOL, nil)
}
//export RefreshLoginByProvider
func RefreshLoginByProvider(provider *C.char) *C.MiaosicResult {
err := miaosic.RefreshLoginByProvider(goString(provider))
if err != nil {
return newResult(nil, C.MIAOSIC_RESULT_BOOL, err)
}
resultData := newBoolResult(true)
return newResult(resultData, C.MIAOSIC_RESULT_BOOL, nil)
}
//export QrLoginByProvider
func QrLoginByProvider(provider *C.char) *C.MiaosicResult {
data, err := miaosic.QrLoginByProvider(goString(provider))
if err != nil {
return newResult(nil, C.MIAOSIC_RESULT_QR_LOGIN_SESSION, err)
}
resultData := newQrLoginSessionResult(data)
return newResult(resultData, C.MIAOSIC_RESULT_QR_LOGIN_SESSION, nil)
}
//export QrLoginVerifyByProvider
func QrLoginVerifyByProvider(provider *C.char, key *C.char, url *C.char) *C.MiaosicResult {
session := &miaosic.QrLoginSession{
Key: goString(key),
Url: goString(url),
}
data, err := miaosic.QrLoginVerifyByProvider(goString(provider), session)
if err != nil {
return newResult(nil, C.MIAOSIC_RESULT_QR_LOGIN_RESULT, err)
}
resultData := newQrLoginResult(data)
return newResult(resultData, C.MIAOSIC_RESULT_QR_LOGIN_RESULT, nil)
}
//export RestoreSessionByProvider
func RestoreSessionByProvider(provider *C.char, session *C.char) *C.MiaosicResult {
err := miaosic.RestoreSessionByProvider(goString(provider), goString(session))
if err != nil {
return newResult(nil, C.MIAOSIC_RESULT_BOOL, err)
}
resultData := newBoolResult(true)
return newResult(resultData, C.MIAOSIC_RESULT_BOOL, nil)
}
//export SaveSessionByProvider
func SaveSessionByProvider(provider *C.char) *C.MiaosicResult {
data, err := miaosic.SaveSessionByProvider(goString(provider))
if err != nil {
return newResult(nil, C.MIAOSIC_RESULT_STRING, err)
}
resultData := newStringResult(data)
return newResult(resultData, C.MIAOSIC_RESULT_STRING, nil)
}
//export UseBilibiliVideo
func UseBilibiliVideo() *C.MiaosicResult {
err := registerProviderIfNeeded(bilivideo.NewBilibiliViedo())
if err != nil {
return newResult(nil, C.MIAOSIC_RESULT_BOOL, err)
}
resultData := newBoolResult(true)
return newResult(resultData, C.MIAOSIC_RESULT_BOOL, nil)
}
//export UseKugou
func UseKugou() *C.MiaosicResult {
err := registerProviderIfNeeded(kugou.NewKugou(false))
if err != nil {
return newResult(nil, C.MIAOSIC_RESULT_BOOL, err)
}
resultData := newBoolResult(true)
return newResult(resultData, C.MIAOSIC_RESULT_BOOL, nil)
}
//export UseKugouInstrumental
func UseKugouInstrumental() *C.MiaosicResult {
if _, ok := miaosic.GetProvider("kugou-instr"); ok {
return newResult(newBoolResult(true), C.MIAOSIC_RESULT_BOOL, nil)
}
kugou.UseInstrumental()
return newResult(newBoolResult(true), C.MIAOSIC_RESULT_BOOL, nil)
}
//export UseKuwo
func UseKuwo() *C.MiaosicResult {
err := registerProviderIfNeeded(kuwo.NewKuwo())
if err != nil {
return newResult(nil, C.MIAOSIC_RESULT_BOOL, err)
}
resultData := newBoolResult(true)
return newResult(resultData, C.MIAOSIC_RESULT_BOOL, nil)
}
//export UseNetease
func UseNetease() *C.MiaosicResult {
err := registerProviderIfNeeded(netease.NewNetease())
if err != nil {
return newResult(nil, C.MIAOSIC_RESULT_BOOL, err)
}
resultData := newBoolResult(true)
return newResult(resultData, C.MIAOSIC_RESULT_BOOL, nil)
}
//export UseQQLogin
func UseQQLogin() *C.MiaosicResult {
if _, ok := miaosic.GetProvider("qq"); ok {
return newResult(newBoolResult(true), C.MIAOSIC_RESULT_BOOL, nil)
}
qq.UseQQLogin()
return newResult(newBoolResult(true), C.MIAOSIC_RESULT_BOOL, nil)
}
//export UseWechatLogin
func UseWechatLogin() *C.MiaosicResult {
if _, ok := miaosic.GetProvider("qq"); ok {
return newResult(newBoolResult(true), C.MIAOSIC_RESULT_BOOL, nil)
}
qq.UseWechatLogin()
return newResult(newBoolResult(true), C.MIAOSIC_RESULT_BOOL, nil)
}
//export UseLocal
func UseLocal(localDir *C.char) *C.MiaosicResult {
err := registerProviderIfNeeded(local.NewLocal(goString(localDir)))
if err != nil {
return newResult(nil, C.MIAOSIC_RESULT_BOOL, err)
}
resultData := newBoolResult(true)
return newResult(resultData, C.MIAOSIC_RESULT_BOOL, nil)
}
func main() {}

152
libmiaosic/libmiaosic.h Normal file
View File

@@ -0,0 +1,152 @@
#ifndef LIBMIAOSIC_H
#define LIBMIAOSIC_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
typedef struct {
char* provider;
char* identifier;
} MiaosicMetaData;
typedef struct {
char* url;
unsigned char* data;
int data_len;
} MiaosicPicture;
typedef struct {
char* title;
char* artist;
MiaosicPicture cover;
char* album;
MiaosicMetaData meta;
} MiaosicMediaInfo;
typedef struct {
char* key;
char* value;
} MiaosicHeaderPair;
typedef struct {
char* url;
char* quality;
MiaosicHeaderPair* headers;
int header_len;
} MiaosicMediaUrl;
typedef struct {
int len;
MiaosicMediaInfo* items;
} MiaosicMediaInfoList;
typedef struct {
int len;
MiaosicMediaUrl* items;
} MiaosicMediaUrlList;
typedef struct {
char* title;
MiaosicMediaInfoList medias;
MiaosicMetaData meta;
} MiaosicPlaylist;
typedef struct {
int matched;
MiaosicMetaData meta;
} MiaosicMatchResult;
typedef struct {
char* url;
char* key;
} MiaosicQrLoginSession;
typedef struct {
int success;
char* message;
} MiaosicQrLoginResult;
typedef struct {
char* lang;
char* lyrics;
} MiaosicLyrics;
typedef struct {
int len;
MiaosicLyrics* items;
} MiaosicLyricsList;
typedef struct {
int value;
} MiaosicBool;
typedef struct {
char* value;
} MiaosicString;
typedef struct {
int len;
char** items;
} MiaosicStringList;
typedef enum {
MIAOSIC_RESULT_NONE = 0,
MIAOSIC_RESULT_BOOL = 1,
MIAOSIC_RESULT_STRING = 2,
MIAOSIC_RESULT_STRING_LIST = 3,
MIAOSIC_RESULT_META = 4,
MIAOSIC_RESULT_MEDIA_INFO = 5,
MIAOSIC_RESULT_MEDIA_INFO_LIST = 6,
MIAOSIC_RESULT_MEDIA_URL_LIST = 7,
MIAOSIC_RESULT_PLAYLIST = 8,
MIAOSIC_RESULT_MATCH = 9,
MIAOSIC_RESULT_QR_LOGIN_SESSION = 10,
MIAOSIC_RESULT_QR_LOGIN_RESULT = 11,
MIAOSIC_RESULT_LYRICS_LIST = 12
} MiaosicResultType;
typedef struct {
int ok;
char* err;
MiaosicResultType result_type;
void* data;
} MiaosicResult;
void FreeResult(MiaosicResult* res);
MiaosicResult* SearchByProvider(const char* provider, const char* keyword, int page, int size);
MiaosicResult* GetMediaUrl(const char* provider, const char* identifier, const char* quality);
MiaosicResult* GetMediaInfo(const char* provider, const char* identifier);
MiaosicResult* GetMediaLyric(const char* provider, const char* identifier);
MiaosicResult* MatchPlaylistByProvider(const char* provider, const char* uri);
MiaosicResult* GetPlaylist(const char* provider, const char* identifier);
MiaosicResult* MatchMedia(const char* keyword);
MiaosicResult* MatchMediaByProvider(const char* provider, const char* uri);
MiaosicResult* ListAvailableProviders(void);
MiaosicResult* LoginByProvider(const char* provider, const char* username, const char* password);
MiaosicResult* LogoutByProvider(const char* provider);
MiaosicResult* IsLoginByProvider(const char* provider);
MiaosicResult* RefreshLoginByProvider(const char* provider);
MiaosicResult* QrLoginByProvider(const char* provider);
MiaosicResult* QrLoginVerifyByProvider(const char* provider, const char* key, const char* url);
MiaosicResult* RestoreSessionByProvider(const char* provider, const char* session);
MiaosicResult* SaveSessionByProvider(const char* provider);
MiaosicResult* UseBilibiliVideo(void);
MiaosicResult* UseKugou(void);
MiaosicResult* UseKugouInstrumental(void);
MiaosicResult* UseKuwo(void);
MiaosicResult* UseNetease(void);
MiaosicResult* UseQQLogin(void);
MiaosicResult* UseWechatLogin(void);
MiaosicResult* UseLocal(const char* local_dir);
#ifdef __cplusplus
}
#endif
#endif