- 0.1.1Latest
- 0.1.0
- 0.0.105
- 0.0.106
- 0.0.103
- 0.0.104
- 0.0.98
- 0.0.97
- 0.0.96
- 0.0.95
- 0.0.94
- 0.0.93
- 0.0.92
- 0.0.91
- 0.0.90
- 0.0.89
- 0.0.88
- 0.0.87
- 0.0.86
- 0.0.85
- 0.0.84
- 0.0.83
- 0.0.82
- 0.0.81
- 0.0.80
- 0.0.79
- 0.0.78
- 0.0.77
- 0.0.76
- 0.0.75
- 0.0.74
- 0.0.73
- 0.0.72
- 0.0.71
- 0.0.70
- 0.0.69
- 0.0.68
- 0.0.67
- 0.0.66
- 0.0.65
- 0.0.64
- 0.0.63
- 0.0.62
- 0.0.61
- 0.0.60
- 0.0.59
- 0.0.58
- 0.0.57
- 0.0.56
- 0.0.55
- 0.0.54
- 0.0.53
- 0.0.52
- 0.0.51
- 0.0.50
- 0.0.49
- 0.0.48
- 0.0.47
- 0.0.46
- 0.0.45
- 0.0.44
- 0.0.43
- 0.0.42
- 0.0.41
- 0.0.40
- 0.0.39
- 0.0.38
- 0.0.37
- 0.0.36
- 0.0.35
- 0.0.34
- 0.0.33
- 0.0.32
- 0.0.31
- 0.0.30
- 0.0.29
- 0.0.28
- 0.0.27
- 0.0.26
- 0.0.25
- 0.0.24
- 0.0.23
- 0.0.22
- 0.0.21
- 0.0.20
- 0.0.19
- 0.0.18
- 0.0.17
- 0.0.16
- 0.0.15
- 0.0.14
- 0.0.13
- 0.0.11
- 0.0.10
- v0.0.9
- v0.0.8
- v0.0.10
- v0.0.6
- v0.0.5
- v0.0.4
- v0.0.3
- v0.0.2
- v0.0.1
muse
A library to interact with the YouTube Music (InnerTube) api.
Note: This library is still in development, and is not ready for production use.
Usage
Donāt forget to replace VERSION
with the
latest version
Deno
import { get_song, search } from "https://deno.land/x/muse@VERSION/mod.ts";
// you can also use the latest version (not recommended) with
// import { get_song, search } from "https://deno.land/x/muse/mod.ts";
// you can also import directly from github
// import { get_song, search } from "https://raw.githubusercontent.com/vixalien/muse/VERSION/mod.ts";
search("drake")
.then((data) => {
console.log("search results", data);
});
get_song("dQw4w9WgXcQ")
.then((data) => {
console.log("song", data);
});
Browser
Youāll need to use a CDN that supports ES modules, such as esm.sh, jspm.io or skypack.dev.
Youāll also need to use a proxy server to get around CORS errors. Itās a good idea to self host the proxy server (cors-anywhere and deno_deploy_cors_proxy are good options).
import { search, set_option } from "https://esm.sh/libmuse@VERSION";
// import { search, set_option } from "https://jspm.dev/npm:libmuse@VERSION";
// import { search, set_option } from "https://cdn.skypack.dev/libmuse@VERSION";
set_option("proxy", "https://proxy.example.com/");
search("top radio")
.then((data) => {
console.log("search results", data);
});
Node
First install using your preferred package manager (npm, yarn, pnpm etc.)
npm install libmuse
Then use it in by importing libmuse
. The Node version has the exact same
features as the Deno version.
import { get_song, search } from "libmuse";
// commonjs: const { get_artist } = require("libmuse");
get_artist("UCvyjk7zKlaFyNIPZ-Pyvkng")
.then((data) => {
console.log("artist", data);
});
For the complete list of operations, see the docs.
Auth
Currently, muse supports oauth authentication by posing as the YouTube TV app.
Hereās the flow:
- Get a login code
- Go to the given login url, and type in the login code on a device that is logged into a google account
- Get the OAuth token & refresh tokens
import { get_option, setup } from "https://deno.land/x/muse@VERSION/mod.ts";
import { RequiresLoginEvent } from "https://deno.land/x/muse@VERSION/auth.ts";
/*
node imports:
import { get_option, setup } from "libmuse";
import { RequiresLoginEvent } from "libmuse/auth.js";
commonjs imports:
const { get_option, setup } = require("libmuse");
const { RequiresLoginEvent } = require("libmuse/auth.js");
*/
const auth = get_option("auth");
setup({
// make sure to persist the token
store: new DenoFileStore("store/muse-store.json"),
debug: true,
});
// this is the authentication flow
const auth_flow = async () => {
if (auth.has_token()) return;
console.log("Getting login code...");
const loginCode = await auth.get_login_code();
console.log(
`Go to ${loginCode.verification_url} and enter the code: ${loginCode.user_code}`,
);
// not necessary, but saves some requests
confirm("Press enter when you have logged in");
console.log("Loading token...");
await auth.load_token_with_code(
loginCode.device_code,
loginCode.interval,
);
console.log("Logged in!", auth._token);
};
// listen to the `requires-login` event, then resolve pass on a function that
// returns a promise that will resolve when the auth flow is complete
auth.addEventListener("requires-login", (event) => {
const resolve = (event as RequiresLoginEvent).detail;
resolve(auth_flow);
});
In the future, I plan to add support for other auth methods, such as cookies and Youtube TV login codes.
Storage
You can pass in a storage object to the client to persist the auth token.
import { setup } from "https://deno.land/x/muse@VERSION/mod.ts";
import {
DenoFileStore,
get_default_store,
LocalStorageStore,
MemoryStore,
Store,
} from "https://deno.land/x/muse@VERSION/store.ts";
/*
npm imports:
import { setup } from "libmuse";
import {
DenoFileStore,
get_default_store,
LocalStorageStore,
MemoryStore,
Store,
} from "libmuse/store.js";
commonjs imports:
const { setup } = require("libmuse");
const {
DenoFileStore,
get_default_store,
LocalStorageStore,
MemoryStore,
Store,
} = require("libmuse/store.js");
*/
// you can use the default store, which is DenoFileStore if available, then LocalStorageStore, then MemoryStore
const client = setup({ store: get_default_store() });
// or you can use any of the built-in stores
const client = setup({ store: new DenoFileStore("/path/to/file.json") });
const client = setup({ store: new LocalStorageStore() });
const client = setup({ store: new MemoryStore() });
// or you can implement your own store
// by extending the Store abstract class
class MyStore extends Store {
get<T>(key: string): T | null;
set(key: string, value: unknown): void;
delete(key: string): void;
}
// then use it accordingly
const client = setup({ store: new MyStore() });
// Do note that setup() can be called multiple times, but it's not recommended.
// this is because setup overrides the global store, so if you call setup()
// multiple times, other options set before will be ignored. example:
setup({ auth: { /* custom auth options */ } });
setup({ store: /* custom store */ });
// the above will only use the custom store, and ignore the custom auth options
Operations
Iām currently targetting to match the ytmusicapiās capabilities.
search
- search
- search suggestions
browsing
- home
- get artist
- get artist albums
- get album
- get album browse id
- get user
- get user playlists
- get song
- get song related
- get lyrics
- get tasteprofile
- set tasteprofile
explore
- get explore
- get mood categories
- get mood playlists
- get charts
- get new releases
watch
- get queue
get watch playlist
library
- get library
- get library playlists
- get library songs
- get library albums
- get library artists
- get library subscriptions
- get liked songs
- get history
- add history item
- remove history items
- rate song
- edit song library status
- rate playlist
- subscribe artists
- unsubscribe artists
playlists
- get playlist
- create playlist
- edit playlist
- delete playlist
- add playlist items
- remove playlist items
uploads
- get library uploads
- get library upload songs
- get library upload artists
- get library upload albums
- get library upload artist
- get library upload album
- upload song (doesnāt currectly work because the TV client canāt do uploads)
- delete upload entity
Acknowledgements
- ytmusicapi - The inspiration for this library
- Youtube Internal Clients - The source of the client names and versions
- many random gists and blog posts whose links Iāve lost