Skip to content

Commit

Permalink
Merge pull request #83 from lovegaoshi/dev-noxplayer
Browse files Browse the repository at this point in the history
feat: ytbi
  • Loading branch information
lovegaoshi authored Jun 4, 2024
2 parents 83b29b4 + cb3d61d commit 88b9810
Show file tree
Hide file tree
Showing 11 changed files with 172 additions and 177 deletions.
2 changes: 1 addition & 1 deletion .prettierrc
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"semi": true,
"tabWidth": 2,
"bracketSpacing": true,
"jsxBracketSameLine": false,
"bracketSameLine": false,
"arrowParens": "always",
"trailingComma": "all"
}
2 changes: 1 addition & 1 deletion azusa-player-mobile
Submodule azusa-player-mobile updated 46 files
+1 −1 __tests__/mediafetch/ytbsearch.test.ts
+16 −10 __tests__/mediafetch/ytbvideo.test.ts
+12 −11 package.json
+4 −4 src/components/bottomtab/NoxBottomTab.tsx
+1 −0 src/components/commonui/AutoComplete.tsx
+1 −1 src/components/dialogs/GenericCheckDialog.tsx
+15 −9 src/components/dialogs/GenericDialog.tsx
+2 −2 src/components/dialogs/NewPlaylistDialog.tsx
+1 −1 src/components/explore/SongRow.tsx
+1 −1 src/components/explore/SongTab.tsx
+1 −1 src/components/player/Lyric.tsx
+3 −3 src/components/player/TrackInfo/AlbumArt.tsx
+1 −1 src/components/player/TrackInfo/RenameSong/RenameSongDialog.tsx
+3 −3 src/components/player/TrackInfo/TrackInfoTemplate.tsx
+1 −1 src/components/player/controls/ThumbsUpButton.tsx
+1 −1 src/components/playlist/Menu/PlaylistSettingsDialog.tsx
+0 −1 src/components/playlist/SongList/SongInfo.tsx
+1 −1 src/components/setting/LanguageSettings.tsx
+1 −1 src/components/setting/plugins/r128gain/Sync.ts
+2 −2 src/components/setting/sync/PersonalCloudAuth.ts
+1 −1 src/components/setting/sync/useSync.ts
+4 −4 src/hooks/useLyric.ts
+1 −1 src/hooks/useLyricRN.ts
+3 −3 src/hooks/usePlaylistCRUD.ts
+1 −1 src/hooks/usePlaylistSetting.ts
+1 −1 src/objects/Song.ts
+1 −1 src/services/PlaybackService.ts
+1 −1 src/stores/useApp.ts
+2 −2 src/stores/useSnack.ts
+1 −3 src/utils/BiliSubscribe.ts
+1 −1 src/utils/Cache.ts
+7 −10 src/utils/ChromeStorage.ts
+1 −3 src/utils/Utils.ts
+6 −1 src/utils/lrcfetch/qqqrc.ts
+1 −1 src/utils/mediafetch/musicfree.ts
+2 −2 src/utils/mediafetch/ytbchannel.ts
+1 −2 src/utils/mediafetch/ytbmixlist.ts
+3 −3 src/utils/mediafetch/ytbplaylist.ts
+3 −4 src/utils/mediafetch/ytbsearch.ts
+57 −0 src/utils/mediafetch/ytbvideo.muse.ts
+230 −0 src/utils/mediafetch/ytbvideo.node.ts
+22 −245 src/utils/mediafetch/ytbvideo.ts
+40 −0 src/utils/mediafetch/ytbvideo.ytbi.ts
+1 −3 src/utils/sync/Gitee.ts
+1 −3 src/utils/sync/Github.ts
+588 −40 yarn.lock
10 changes: 5 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"@babel/preset-env": "^7.24.6",
"@babel/preset-react": "^7.24.6",
"@babel/preset-typescript": "^7.24.6",
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.13",
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.15",
"@types/base-64": "^1.0.2",
"@types/chrome": "^0.0.268",
"@types/he": "^1.2.3",
Expand All @@ -30,8 +30,8 @@
"@types/react": "^18.3.3",
"@types/react-dom": "^18.3.0",
"@types/uuid": "^9.0.8",
"@typescript-eslint/eslint-plugin": "^7.11.0",
"@typescript-eslint/parser": "^7.11.0",
"@typescript-eslint/eslint-plugin": "^7.12.0",
"@typescript-eslint/parser": "^7.12.0",
"@welldone-software/why-did-you-render": "^8.0.1",
"babel-loader": "^9.1.3",
"clean-webpack-plugin": "^4.0.0",
Expand All @@ -53,7 +53,7 @@
"lodash": "^4.17.21",
"mini-css-extract-plugin": "^2.9.0",
"node-sass": "^9.0.0",
"prettier": "^3.2.5",
"prettier": "^3.3.0",
"progress-bar-webpack-plugin": "^2.1.0",
"react-refresh": "^0.14.2",
"sass-loader": "^14.2.1",
Expand Down Expand Up @@ -102,7 +102,7 @@
"fs": "^0.0.1-security",
"he": "^1.2.0",
"i18next": "^23.11.5",
"libmuse": "git+https://github.com/lovegaoshi/muse.git#apm-release",
"libmuse": "https://github.com/lovegaoshi/muse.git#commit=cbb249107f71a2f57336a5d08fac389138d8c924",
"material-ui-confirm": "^3.0.16",
"md5": "^2.3.0",
"notistack": "^3.0.1",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,15 @@ import { SxProps } from '@mui/material';

interface Props {
sx?: SxProps;
playlist: NoxMedia.Playlist;
handleAddToFavClick: (v: NoxMedia.Playlist) => void;
handleAddToFavClick: () => void;
}
export default function DeletePlaylistButton({
sx,
playlist,
handleAddToFavClick,
}: Props) {
return (
<Tooltip title='添加到收藏歌单'>
<AddBoxOutlinedIcon
sx={sx}
onClick={() => handleAddToFavClick(playlist)}
/>
<AddBoxOutlinedIcon sx={sx} onClick={() => handleAddToFavClick()} />
</Tooltip>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,15 @@ import { SxProps } from '@mui/material';

interface Props {
sx?: SxProps;
playlist: NoxMedia.Playlist;
handleCreateAsFavClick: (v: NoxMedia.Song[]) => void;
handleCreateAsFavClick: () => void;
}
export default function DeletePlaylistButton({
sx,
playlist,
handleCreateAsFavClick,
}: Props) {
return (
<Tooltip title='新建为歌单'>
<FiberNewIcon
sx={sx}
onClick={() => handleCreateAsFavClick(playlist.songList)}
/>
<FiberNewIcon sx={sx} onClick={() => handleCreateAsFavClick()} />
</Tooltip>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,15 @@ import { SxProps } from '@mui/material';

interface Props {
sx?: SxProps;
playlist: NoxMedia.Playlist;
handleDeleteFavClick: (v: NoxMedia.Playlist) => void;
handleDeleteFavClick: () => void;
}
export default function DeletePlaylistButton({
sx,
playlist,
handleDeleteFavClick,
}: Props) {
return (
<Tooltip title='删除歌单'>
<DeleteOutlineOutlinedIcon
sx={sx}
onClick={() => handleDeleteFavClick(playlist)}
/>
<DeleteOutlineOutlinedIcon sx={sx} onClick={handleDeleteFavClick} />
</Tooltip>
);
}
11 changes: 3 additions & 8 deletions src/components/Playlists/PlaylistsList/ButtonPlayPlaylist.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,12 @@ import { SxProps } from '@mui/material';

interface Props {
sx?: SxProps;
playlist: NoxMedia.Playlist;
onPlayAllFromFav: (v: NoxMedia.Playlist) => void;
onPlayAllFromFav: () => void;
}
export default function DeletePlaylistButton({
sx,
playlist,
onPlayAllFromFav,
}: Props) {
export default function DeletePlaylistButton({ sx, onPlayAllFromFav }: Props) {
return (
<Tooltip title='播放歌单'>
<PlaylistPlayIcon sx={sx} onClick={() => onPlayAllFromFav(playlist)} />
<PlaylistPlayIcon sx={sx} onClick={onPlayAllFromFav} />
</Tooltip>
);
}
27 changes: 15 additions & 12 deletions src/components/Playlists/PlaylistsList/PlaylistInfo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -103,23 +103,24 @@ export function PlaylistInfo(props: Props) {
} = props;
const playerStyle = useApp((state) => state.playerStyle);
const { CRUDBtn, CRUDIcon } = playerStyle;
const getPlaylist = useNoxSetting((state) => state.getPlaylist);

return (
<PlaylistInfoBase {...props}>
<Box component='div' sx={CRUDBtn}>
<PlayPlaylistButton
sx={CRUDIcon}
playlist={playlist}
onPlayAllFromFav={onPlayAllFromFav}
onPlayAllFromFav={() =>
getPlaylist(playlist.id).then(onPlayAllFromFav)
}
/>
<AddToPlaylistButton
sx={CRUDIcon}
playlist={playlist}
handleAddToFavClick={handleAddToFavClick}
handleAddToFavClick={() => handleAddToFavClick(playlist)}
/>
<DeletePlaylistButton
sx={CRUDIcon}
playlist={playlist}
handleDeleteFavClick={handleDeleteFavClick}
handleDeleteFavClick={() => handleDeleteFavClick(playlist)}
/>
</Box>
</PlaylistInfoBase>
Expand All @@ -134,24 +135,26 @@ export function SearchlistEntry(props: Props) {
handleCreateAsFavClick,
} = props;
const { CRUDBtn, CRUDIcon } = useApp((state) => state.playerStyle);
const getPlaylist = useNoxSetting((state) => state.getPlaylist);

return (
<PlaylistInfoBase {...props} albumIcon={<ManageSearchIcon />}>
<Box component='div' sx={CRUDBtn}>
<PlayPlaylistButton
sx={CRUDIcon}
playlist={playlist}
onPlayAllFromFav={onPlayAllFromFav}
onPlayAllFromFav={() => onPlayAllFromFav(playlist)}
/>
<AddToPlaylistButton
sx={CRUDIcon}
playlist={playlist}
handleAddToFavClick={handleAddToFavClick}
handleAddToFavClick={() => handleAddToFavClick(playlist)}
/>
<CreateAsPlaylistButton
sx={CRUDIcon}
playlist={playlist}
handleCreateAsFavClick={handleCreateAsFavClick}
handleCreateAsFavClick={() =>
getPlaylist(playlist.id).then((v) =>
handleCreateAsFavClick(v.songList),
)
}
/>
</Box>
</PlaylistInfoBase>
Expand Down
73 changes: 12 additions & 61 deletions src/utils/mediafetch/ytbvideo.ts
Original file line number Diff line number Diff line change
@@ -1,34 +1,16 @@
// eslint-disable-next-line import/no-extraneous-dependencies, camelcase
import { get_song } from 'libmuse';

import { biliApiLimiter } from '@APM/utils/mediafetch/throttle';
import SongTS from '@objects/Song';
import { Source } from '@enums/MediaFetch';

export const CIDPREFIX = `${Source.ytbvideo}-`;

const resolveURL = async (song: NoxMedia.Song) => {
const extractedVideoInfo = await get_song(song.bvid);
let maxAudioQualityStream = { bitrate: 0, url: '' };
const formats =
extractedVideoInfo.adaptive_formats ?? extractedVideoInfo.formats ?? [];
// eslint-disable-next-line no-restricted-syntax
for (const videoStream of formats) {
if (
videoStream.has_audio &&
videoStream.bitrate > maxAudioQualityStream.bitrate &&
videoStream.codecs.includes('mp4a')
) {
maxAudioQualityStream = videoStream;
}
}
return {
...maxAudioQualityStream,
loudness: extractedVideoInfo.playerConfig.audioConfig.loudnessDb,
perceivedLoudness:
extractedVideoInfo.playerConfig.audioConfig.perceptualLoudnessDb,
};
};
import {
resolveURL as resolveURLMuse,
fetchAudioInfo as fetchAudioInfoMuse,
} from '@APM/utils/mediafetch/ytbvideo.muse';
import {
resolveURL as resolveURLYtbi,
fetchAudioInfo as fetchAudioInfoYtbi,
} from './ytbvideo.ytbi';

const resolveURL = (song: NoxMedia.Song) =>
resolveURLYtbi(song).catch(() => resolveURLMuse(song));

const refreshSong = (song: NoxMedia.Song) => song;

Expand All @@ -45,40 +27,9 @@ export const fetchAudioInfo = (
) =>
biliApiLimiter.schedule(() => {
progressEmitter();
return fetchAudioInfoRaw(bvid);
return fetchAudioInfoYtbi(bvid).catch(() => fetchAudioInfoMuse(bvid));
});

const fetchAudioInfoRaw = async (sid: string) => {
const ytdlInfo = await get_song(sid);
console.debug(ytdlInfo);
const { videoDetails } = ytdlInfo;
const formats = ytdlInfo.adaptive_formats ?? ytdlInfo.formats ?? [];
const validDurations = formats.filter((format) => format.duration_ms);
return [
SongTS({
cid: `${CIDPREFIX}-${sid}`,
bvid: sid,
name: videoDetails.title,
nameRaw: videoDetails.title,
singer: videoDetails.author,
singerId: videoDetails.channelId,
cover:
videoDetails.thumbnail.thumbnails[
videoDetails.thumbnail.thumbnails.length - 1
]!.url,
lyric: '',
page: 1,
duration:
validDurations.length > 0
? Math.floor(validDurations[0]!.duration_ms / 1000)
: 0,
album: videoDetails.title,
source: Source.ytbvideo,
metadataOnLoad: true,
}),
];
};

export default {
regexSearchMatch: /youtu(?:.*\/v\/|.*v=|\.be\/)([A-Za-z0-9_-]{11})/,
resolveURL,
Expand Down
52 changes: 52 additions & 0 deletions src/utils/mediafetch/ytbvideo.ytbi.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import SongTS from '@objects/Song';
import { Source } from '@enums/MediaFetch';
import { Innertube } from 'youtubei.js/web';

const ytClient = Innertube.create({
fetch: async (input, init?: RequestInit) => {
// Modify the request
// and send it to the proxy

// fetch the URL

// @ts-expect-error
return fetch(input, init);
},
});

export const resolveURL = async (song: NoxMedia.Song) => {
const yt = await ytClient;
const extractedVideoInfo = await yt.getInfo(song.bvid);
const maxAudioQualityStream = extractedVideoInfo.chooseFormat({
quality: 'best',
type: 'audio',
});
return {
url: maxAudioQualityStream.decipher(yt.session.player),
loudness: maxAudioQualityStream.loudness_db,
};
};

export const fetchAudioInfo = async (sid: string) => {
const yt = await ytClient;
const videoInfo = (await yt.getBasicInfo(sid)).basic_info;
return [
SongTS({
cid: `${Source.ytbvideo}-${sid}`,
bvid: sid,
name: videoInfo.title!,
nameRaw: videoInfo.title!,
singer: videoInfo.author!,
singerId: videoInfo.channel_id!,
cover: videoInfo.thumbnail
? videoInfo.thumbnail[videoInfo.thumbnail.length - 1]!.url
: '',
lyric: '',
page: 1,
duration: videoInfo.duration,
album: videoInfo.title!,
source: Source.ytbvideo,
metadataOnLoad: true,
}),
];
};
Loading

0 comments on commit 88b9810

Please sign in to comment.