@khang07/zing-mp3-api
v1.6.1
Published
The basic APIs provide the features of ZingMp3
Maintainers
Readme
A TypeScript library for working with Zing MP3 resources from Node.js. It supports searching songs, videos, playlists, and artists; fetching metadata; and returning readable streams for music and video playback or download.
For source code, releases, and package metadata, see the GitHub repository and the npm package. Report bugs or request features in the issue tracker.
Table of contents
- Requirements
- Installation
- Configuration
- Usage
- API reference
- Public exports
- Error handling
- Troubleshooting & FAQ
- Maintainers
- License
Requirements
This package requires a modern Node.js environment and network access to Zing MP3.
Project dependencies:
Development dependencies:
Installation
npm install @khang07/zing-mp3-apiBuild from source:
npm run buildRun tests:
npm testRun live integration tests:
ZING_MP3_LIVE=1 npm testConfiguration
Use the default exported client for quick access, or create a custom Client
instance when you need to override options.
Create a custom client
import { Client, Cookies } from "@khang07/zing-mp3-api";
const client = new Client({
maxLoad: 1024 * 1024,
maxHighWaterMark: 16 * 1024,
userAgent:
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 " +
"(KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3",
jar: new Cookies()
});Update the default client
import client from "@khang07/zing-mp3-api";
client.setOptions({
maxLoad: 1024 * 1024,
maxHighWaterMark: 16 * 1024,
userAgent:
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 " +
"(KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3",
jar: client.getJar()
});ClientOptions:
maxLoad: request rate limit passed to Axios asmaxRatemaxHighWaterMark: stream buffer size used bymusicSync()andvideoSync()userAgent: custom request user-agent stringjar: custom cookie jar instance
The client automatically fetches and stores cookies before protected requests.
Usage
ESM
import client, { Client } from "@khang07/zing-mp3-api";CommonJS
const { default: client, Client } = require("@khang07/zing-mp3-api");Search songs
const items = await client.searchMusic("Skyfall");
console.log(items[0]);Fetch playlist details
const playlist = await client.playlist(
"https://zingmp3.vn/album/example/ZWZB9WAB.html"
);
console.log(playlist.name);
console.log(playlist.mediaCount);Fetch artist details
const artist = await client.artist("https://zingmp3.vn/Obito");
console.log(artist.name);
console.log(artist.followCount);Download a music stream
import { createWriteStream } from "node:fs";
const items = await client.searchMusic("Example");
const stream = await client.music(items[0].id);
stream.pipe(createWriteStream("music.mp3"));Download a video stream
import { createWriteStream } from "node:fs";
const items = await client.searchVideo("Example");
const stream = await client.video(items[0].id);
stream.pipe(createWriteStream("video.ts"));Use the immediate stream APIs
import { createWriteStream } from "node:fs";
const stream = client.musicSync("Example ID");
stream.pipe(createWriteStream("music.mp3"));Handle library errors
import client, { Lapse } from "@khang07/zing-mp3-api";
try {
await client.playlist("");
} catch (error) {
if (error instanceof Lapse) {
console.error(error.name);
console.error(error.code);
console.error(error.status);
console.error(error.cause);
}
}API reference
new Client(options?)
Creates a new client instance.
Client.getIDFromURL(url)
Extracts a resource token or alias from a Zing MP3 URL.
Throws ERROR_INVALID_URL when the input is empty or unsupported.
Instance methods
| Method | Returns | Description |
| ----------------------- | --------------------------- | -------------------------------------------------------------------------------- |
| getJar() | Cookies | Returns the current cookie jar. |
| setOptions(options?) | void | Updates client options. |
| video(videoID) | Promise<Readable> | Fetches a video stream from an ID, URL string, or URL object. |
| videoSync(videoID) | Readable | Returns a PassThrough immediately and pipes the resolved video stream into it. |
| music(musicID) | Promise<Readable> | Fetches a music stream from an ID, URL string, or URL object. |
| musicSync(musicID) | Readable | Returns a PassThrough immediately and pipes the resolved music stream into it. |
| playlist(playlistID) | Promise<PlayList> | Fetches playlist details. |
| artist(aliasID) | Promise<Artist> | Fetches artist details. |
| mediaDetails(mediaID) | Promise<Media> | Fetches song details. |
| search(query, type) | Promise<SearchObj[type][]>| Searches. |
| releaseChart() | Promise<MediaChart[]> | Gets the latest ranking list. |
Method notes
video()prefers720pand falls back to360pmusic()prefers320kbpsand falls back to128kbps- if the main music endpoint returns VIP-only data,
music()retries the extra endpoint before throwingERROR_MUSIC_VIP_ONLY - search methods currently request the first page with
count: 20 musicSync()andvideoSync()forward stream failures to the returnedPassThroughand destroy the source stream when the output is closed
Public exports
Runtime exports
default: ready-to-useClientinstanceClient: client classCookies: cookie jar classcreateSignature: signature functionLapse: custom error class
Type exports
ClientOptionsArtistMediaPlayListSearchArtistSearchMediaSearchPlayListMediaChart
Cookies helper
Methods:
setCookie(setCookie, requestUrl)setCookies(setCookies, requestUrl)getCookies(requestUrl)getCookieHeader(requestUrl)applyToHeaders(requestUrl, headers?)deleteCookie(domain, path, name)cleanup()toJSON()fromJSON(cookies)
interface CookieRecord {
name: string;
value: string;
domain: string;
path: string;
expiresAt?: number;
secure: boolean;
httpOnly: boolean;
sameSite?: "Strict" | "Lax" | "None";
hostOnly: boolean;
}Example:
import { Cookies } from "@khang07/zing-mp3-api";
const jar = new Cookies();
jar.setCookie("sid=abc; Path=/; HttpOnly", "https://zingmp3.vn/");
console.log(jar.getCookieHeader("https://zingmp3.vn/"));Error handling
The library throws Lapse, a custom error type with these fields:
namemessagecodestatuscause
Known error codes:
ERROR_ARTIST_FETCHERROR_ARTIST_NOT_FOUNDERROR_INVALID_IDERROR_INVALID_QUERYERROR_INVALID_TYPEERROR_INVALID_URLERROR_MEDIA_FETCHERROR_MEDIA_NOT_FOUNDERROR_MUSIC_FETCHERROR_MUSIC_VIP_ONLYERROR_PLAYLIST_FETCHERROR_PLAYLIST_NOT_FOUNDERROR_SEARCH_FAILEDERROR_SEARCH_FETCHERROR_STREAM_DOWNLOADERROR_STREAM_URL_NOT_FOUNDERROR_VIDEO_FETCHERROR_VIDEO_NOT_FOUNDERROR_RELEASE_CHART_FETCH
Troubleshooting & FAQ
video() returns a stream, but saved files do not open as MP4
Video playback is fetched from an HLS source via m3u8stream. If you write the
stream directly to disk, save it as .ts or post-process it with your own media pipeline.
Music lookup fails with ERROR_MUSIC_VIP_ONLY
Some tracks are restricted. The fallback endpoint may still return no playable URL.
I want to reuse cookies between sessions
Use jar.toJSON() to persist cookies and jar.fromJSON() to restore them.
Input URLs fail with ERROR_INVALID_URL
Use a standard Zing MP3 HTML URL such as
https://zingmp3.vn/bai-hat/test/ZWZB9WAB.html or a root-style artist URL such as
https://zingmp3.vn/mono.
Maintainers
- GiaKhang - GiaKhang1810
License
This project is licensed under the MIT License. See the LICENSE file for details.
