跳转至

SongApi

modules.song.SongApi

SongApi(client: Client)

Bases: ApiModule

歌曲相关 API 模块类.

Source code in qqmusic_api/modules/_base.py
def __init__(self, client: "Client") -> None:
    self._client = client
    self._session = client._session

query_song

query_song(song_info: list[SongQueryInfo])

批量获取歌曲信息.

PARAMETER DESCRIPTION
song_info

SongQueryInfo 列表.

TYPE: list[SongQueryInfo]

RAISES DESCRIPTION
ValueError

如果 song_info 为空, 或参数不匹配.

Source code in qqmusic_api/modules/song.py
def query_song(
    self,
    song_info: list[SongQueryInfo],
):
    """批量获取歌曲信息.

    Args:
        song_info: SongQueryInfo 列表.

    Raises:
        ValueError: 如果 `song_info` 为空, 或参数不匹配.
    """
    if not song_info:
        raise ValueError("song_info 不能为空")

    ids, mids, types = [], [], []
    for item in song_info:
        if (item.id is None) == (item.mid is None):
            raise ValueError("SongQueryInfo 必须提供 id 或 mid 且不能同时提供")

        if item.id is not None:
            ids.append(item.id)
        else:
            mids.append(item.mid)
        types.append(item.song_type or 0)

    params: dict[str, Any] = {
        "ctx": 0,
        "client": 1,
        "types": types,
        "modify_stamp": [0] * len(types),
    }

    if ids:
        params["ids"] = ids
    if mids:
        params["mids"] = mids

    return self._build_cgi(
        module="music.trackInfo.UniformRuleCtrl",
        method="CgiGetTrackInfo",
        param=params,
        response_model=QuerySongResponse,
    )

get_cdn_dispatch

get_cdn_dispatch()

获取音频链接 CDN 信息.

Source code in qqmusic_api/modules/song.py
def get_cdn_dispatch(self):
    """获取音频链接 CDN 信息."""
    return self._build_cgi(
        module="music.audioCdnDispatch.cdnDispatch",
        method="GetCdnDispatch",
        param={
            "guid": get_guid(),
            "uid": "0",
            "use_new_domain": 1,
            "use_ipv6": 1,
        },
        response_model=GetCdnDispatchResponse,
    )

get_song_urls

get_song_urls(
    file_info: list[SongFileInfo],
    file_type: BaseSongFileType = MP3_128,
    credential: Credential | None = None,
)

获取歌曲文件链接.

PARAMETER DESCRIPTION
file_info

歌曲文件信息列表.

TYPE: list[SongFileInfo]

file_type

歌曲文件类型.

TYPE: BaseSongFileType DEFAULT: MP3_128

credential

凭据对象.

TYPE: Credential | None DEFAULT: None

RAISES DESCRIPTION
ValueError

mid 数量超过上限时抛出.

Source code in qqmusic_api/modules/song.py
def get_song_urls(
    self,
    file_info: list[SongFileInfo],
    file_type: BaseSongFileType = SongFileType.MP3_128,
    credential: Credential | None = None,
):
    """获取歌曲文件链接.

    Args:
        file_info: 歌曲文件信息列表.
        file_type: 歌曲文件类型.
        credential: 凭据对象.

    Raises:
        ValueError: 当 `mid` 数量超过上限时抛出.
    """
    encrypted = isinstance(file_type, EncryptedSongFileType)
    module, method = (
        ("music.vkey.GetVkey", "UrlGetVkey") if not encrypted else ("music.vkey.GetEVkey", "CgiGetEVkey")
    )
    songmid: list[str] = []
    filename: list[str] = []
    songtype: list[int] = []
    for item in file_info:
        songmid.append(item.mid)
        final_file_type = item.file_type or file_type

        filename.append(
            f"{final_file_type.s}{item.mid}{item.mid}{final_file_type.e}"
            if not item.media_mid
            else f"{final_file_type.s}{item.media_mid}{final_file_type.e}",
        )
        songtype.append(item.song_type or 0)

    return self._build_cgi(
        module=module,
        method=method,
        param={
            "uin": self._client.credential.str_musicid if not credential else credential.str_musicid,
            "filename": filename,
            "guid": get_guid(),
            "songmid": songmid,
            "songtype": songtype,
            "ctx": 0,
        },
        response_model=GetSongUrlsResponse,
        credential=credential,
    )

get_detail

get_detail(value: int | str)

获取歌曲详细信息.

固定使用 Web 平台.

PARAMETER DESCRIPTION
value

歌曲 ID 或 MID.

TYPE: int | str

Source code in qqmusic_api/modules/song.py
def get_detail(self, value: int | str):
    """获取歌曲详细信息.

    固定使用 Web 平台.

    Args:
        value: 歌曲 ID 或 MID.
    """
    param = (
        {"song_id": int(value)}
        if isinstance(value, int) or (isinstance(value, str) and value.isdecimal())
        else {"song_mid": value}
    )
    return self._build_cgi(
        module="music.pf_song_detail_svr",
        method="get_song_detail_yqq",
        param=param,
        platform=Platform.WEB,
        response_model=GetSongDetailResponse,
    )

get_similar_song

get_similar_song(songid: int)

获取相似歌曲.

PARAMETER DESCRIPTION
songid

歌曲 ID.

TYPE: int

Source code in qqmusic_api/modules/song.py
def get_similar_song(self, songid: int):
    """获取相似歌曲.

    Args:
        songid: 歌曲 ID.
    """
    return self._build_cgi(
        module="music.recommend.TrackRelationServer",
        method="GetSimilarSongs",
        param={"songid": songid},
        response_model=GetSimilarSongResponse,
    )

get_labels

get_labels(songid: int)

获取歌曲标签.

PARAMETER DESCRIPTION
songid

歌曲 ID.

TYPE: int

Source code in qqmusic_api/modules/song.py
def get_labels(self, songid: int):
    """获取歌曲标签.

    Args:
        songid: 歌曲 ID.
    """
    return self._build_cgi(
        module="music.recommend.TrackRelationServer",
        method="GetSongLabels",
        param={"songid": songid},
        response_model=GetSongLabelsResponse,
    )
get_related_songlist(
    songid: int, last: list[int] | None = None
)

获取歌曲相关歌单.

PARAMETER DESCRIPTION
songid

歌曲 ID.

TYPE: int

last

上次请求的相关歌单 ID 列表, 用于换一批歌单.

TYPE: list[int] | None DEFAULT: None

Source code in qqmusic_api/modules/song.py
def get_related_songlist(self, songid: int, last: list[int] | None = None):
    """获取歌曲相关歌单.

    Args:
        songid: 歌曲 ID.
        last: 上次请求的相关歌单 ID 列表, 用于换一批歌单.
    """
    return self._build_cgi(
        module="music.recommend.TrackRelationServer",
        method="GetRelatedPlaylist",
        param={"songid": songid, "vecPlaylist": last or []},
        response_model=GetRelatedSonglistResponse,
        pager_strategy=BatchRefreshStrategy[GetRelatedSonglistResponse](
            refresh_key="vecPlaylist",
            has_more_extractor=lambda r: bool(r.has_more),
            cursor_extractor=lambda r: [playlist.id for playlist in r.songlist] if r.songlist else None,
        ),
    ).with_extractor(lambda r: r.songlist)
get_related_mv(songid: int, last_mvid: str | None = None)

获取歌曲相关 MV.

PARAMETER DESCRIPTION
songid

歌曲 ID.

TYPE: int

last_mvid

上一个 MV 的 VID (可选).

TYPE: str | None DEFAULT: None

Source code in qqmusic_api/modules/song.py
def get_related_mv(self, songid: int, last_mvid: str | None = None):
    """获取歌曲相关 MV.

    Args:
        songid: 歌曲 ID.
        last_mvid: 上一个 MV 的 VID (可选).
    """
    return self._build_cgi(
        module="MvService.MvInfoProServer",
        method="GetSongRelatedMv",
        param={"songid": str(songid), "songtype": 1, "lastmvid": last_mvid or 0},
        response_model=GetRelatedMvResponse,
        pager_strategy=BatchRefreshStrategy[GetRelatedMvResponse](
            refresh_key="lastmvid",
            has_more_extractor=lambda r: bool(r.has_more),
            cursor_extractor=lambda r: r.mv[-1].id if r.mv else None,
        ),
    ).with_extractor(lambda r: r.mv)

get_other_version

get_other_version(value: int | str)

获取歌曲其他版本.

PARAMETER DESCRIPTION
value

歌曲 ID 或 MID.

TYPE: int | str

Source code in qqmusic_api/modules/song.py
def get_other_version(self, value: int | str):
    """获取歌曲其他版本.

    Args:
        value: 歌曲 ID 或 MID.
    """
    param = (
        {"songid": int(value)}
        if isinstance(value, int) or (isinstance(value, str) and value.isdecimal())
        else {"songmid": value}
    )
    return self._build_cgi(
        module="music.musichallSong.OtherVersionServer",
        method="GetOtherVersionSongs",
        param=param,
        response_model=GetOtherVersionResponse,
    )

get_producer

get_producer(value: int | str)

获取歌曲制作人信息.

PARAMETER DESCRIPTION
value

歌曲 ID 或 MID.

TYPE: int | str

Source code in qqmusic_api/modules/song.py
def get_producer(self, value: int | str):
    """获取歌曲制作人信息.

    Args:
        value: 歌曲 ID 或 MID.
    """
    param = (
        {"songid": int(value)}
        if isinstance(value, int) or (isinstance(value, str) and value.isdecimal())
        else {"songmid": value}
    )
    return self._build_cgi(
        module="music.sociality.KolWorksTag",
        method="SongProducer",
        param=param,
        response_model=GetProducerResponse,
    )

get_sheet

get_sheet(mid: str, ttype: int = 0)

获取歌曲相关曲谱.

PARAMETER DESCRIPTION
mid

歌曲 MID.

TYPE: str

ttype

曲谱来源类型. 0=用户上传, 1=引擎/AI曲谱, 2=虫虫钢琴.

TYPE: int DEFAULT: 0

Source code in qqmusic_api/modules/song.py
def get_sheet(self, mid: str, ttype: int = 0):
    """获取歌曲相关曲谱.

    Args:
        mid: 歌曲 MID.
        ttype: 曲谱来源类型. 0=用户上传, 1=引擎/AI曲谱, 2=虫虫钢琴.
    """
    if ttype == 2:
        return self._build_cgi(
            module="music.mir.SheetMusicSvr",
            method="GetChongChongSheetMusic",
            param={"songMid": mid, "begin": 0, "end": 100, "scoreType": -1, "ttype": 1},
            response_model=GetSheetResponse,
            comm={
                "g_tk": 5381,
                "uin": "",
                "format": "json",
                "inCharset": "utf-8",
                "outCharset": "utf-8",
                "notice": 0,
                "platform": "h5",
                "needNewCode": 1,
            },
            sign=True,
            override_comm=True,
            allow_error_codes={10007},
            parse_on_allow=True,
        )
    score_type = -473 if ttype == 1 else -1
    return self._build_cgi(
        module="music.mir.SheetMusicSvr",
        method="GetMoreSheetMusic",
        param={"songMid": mid, "begin": 0, "end": 100, "scoreType": score_type, "ttype": ttype},
        response_model=GetSheetResponse,
        comm={
            "g_tk": 5381,
            "uin": "",
            "format": "json",
            "inCharset": "utf-8",
            "outCharset": "utf-8",
            "notice": 0,
            "needNewCode": 1,
        },
        override_comm=True,
        allow_error_codes={10007},
        parse_on_allow=True,
    )

has_sheet

has_sheet(mid: str)

检查歌曲是否有曲谱.

PARAMETER DESCRIPTION
mid

歌曲 MID.

TYPE: str

Source code in qqmusic_api/modules/song.py
def has_sheet(self, mid: str):
    """检查歌曲是否有曲谱.

    Args:
        mid: 歌曲 MID.
    """
    return self._build_cgi(
        module="music.mir.SheetMusicSvr",
        method="HasSheetMusic",
        param={"songMid": mid},
        response_model=HasSheetMusicResponse,
        comm={
            "g_tk": 5381,
            "uin": "",
            "format": "json",
            "inCharset": "utf-8",
            "outCharset": "utf-8",
            "notice": 0,
            "needNewCode": 1,
        },
        override_comm=True,
    )

get_fav_num

get_fav_num(song_ids: list[int])

获取歌曲收藏数量原始数据.

PARAMETER DESCRIPTION
song_ids

歌曲 ID 列表.

TYPE: list[int]

Source code in qqmusic_api/modules/song.py
def get_fav_num(self, song_ids: list[int]):
    """获取歌曲收藏数量原始数据.

    Args:
        song_ids: 歌曲 ID 列表.
    """
    return self._build_cgi(
        module="music.musicasset.SongFavRead",
        method="GetSongFansNumberById",
        param={"v_songId": song_ids},
        response_model=GetFavNumResponse,
    )