Skip to main content

🎵 akuibots-musical (Python)

PyPI — versi Python Lisensi

Plugin musik untuk bot — bukan bot-nya. Kirim judul atau link (YouTube / Spotify), plugin balas metadata lengkap: thumbnail, judul, durasi, pembuat — plus audio stream yang siap diputar di voice bot.

🟢 Versi Node.js: akuibots-musical di npm — API-nya sengaja dibuat mirip, tinggal pindah bahasa.

from akuibots_musical import Musical

music = Musical()

track = music.play("a!p alan walker faded")   # judul → dicari otomatis di YouTube
track = music.play("https://youtu.be/60ItHLz5WEA")                          # link YouTube
track = music.play("https://open.spotify.com/track/4uLU6hMCjMI75M1A2tKUQC") # link Spotify

print(track.title)          # Alan Walker - Faded
print(track.author)         # Alan Walker
print(track.duration_text)  # 3:33
print(track.thumbnail)      # https://i.ytimg.com/vi/.../hqdefault.jpg

handle = music.get_stream(track)
print(handle.url)           # URL audio → pipa ke ffmpeg (voice bot)

✨ Fitur

  • 🔎 Kirim judul → dicari otomatis di YouTube (kayak ytsearch), ambil hasil teratas
  • 🔗 Kirim link → YouTube (watch / youtu.be / shorts / live / music) & Spotify (track / album / playlist / artist) langsung dikenali
  • 🖼️ Data lengkap: thumbnail, judul, durasi, pembuat (uploader), views, status live
  • 🔊 Audio stream siap dipipa ke ffmpeg — discord.py, py-cord, Telegram, CLI, apa saja
  • ⚡ Tanpa Lavalink, tanpa API key, tanpa browser headless
  • 🧹 Pembersih perintah otomatis: a!p faded, !play faded, music-bot!p faded → faded
  • 🌐 Spotify tanpa API key (token anonim embed + fallback oEmbed) → dicocokkan ke YouTube untuk audionya
  • 🐍 Dependency minimal: yt-dlp + requests — Python ≥ 3.8
  • 🌀 Async ready: play_async() dkk. untuk bot berbasis asyncio (discord.py, dll)

📦 Instalasi

pip install akuibots-musical

Untuk memutar audio di voice bot kamu juga butuh ffmpeg terpasang di server (apt install ffmpeg / brew install ffmpeg).

🚀 Quick Start

1 — Instal:

pip install akuibots-musical

2 — Play dari judul (alur a!p):

from akuibots_musical import Musical

music = Musical()
track = music.play("a!p alan walker faded")
# prefix 'a!p' otomatis dibuang → dicari 'alan walker faded' di YouTube

3 — Play dari link (YouTube / Spotify):

track = music.play("https://www.youtube.com/watch?v=60ItHLz5WEA")
track = music.play("https://open.spotify.com/track/4uLU6hMCjMI75M1A2tKUQC")
# Spotify → metadata diambil tanpa API key, lalu dicocokkan ke YouTube

4 — Ambil audio untuk voice:

handle = music.get_stream(track)      # atau music.get_stream("a!p faded")
print(handle.url)                     # URL audio langsung (m4a/opus)

📦 Isi Track

Field Tipe Contoh Keterangan
id str 60ItHLz5WEA video ID YouTube
title str Alan Walker - Faded judul
author str Alan Walker pembuat / uploader
duration int | None 213 durasi dalam detik (None kalau live)
duration_text str "3:33" / "Live" durasi siap tampil
duration_ms property 213000 durasi dalam milidetik
thumbnail str https://i.ytimg.com/vi/... gambar thumbnail
url str https://www.youtube.com/watch?v=... halaman YouTube
is_live bool False sedang live?
view_count int | None 3500000000 jumlah views
source str "youtube" / "spotify" asal track
spotify_url str | None link Spotify asal (kalau dari Spotify)
spotify_title str | None judul asli di Spotify
spotify_author str | None artis asli di Spotify
query str | None alan walker faded judul yang diketik user
to_dict() → dict semua field sebagai dict

🔊 Isi StreamHandle

Field / Method Keterangan
handle.url URL audio langsung (m4a/opus; live = HLS m3u8) → pipa ke ffmpeg
handle.ext / handle.abr / handle.format_id info format audio
handle.is_live True kalau live stream
handle.track objek Track asalnya
handle.iter_chunks(size=65536) generator byte audio (untuk relay manual)
handle.save(path) unduh audio ke file
handle.popen() subprocess yt-dlp → byte audio mentah di proc.stdout (paling tahan bot-check)
handle.pcm_popen() yt-dlp → ffmpeg → PCM siap discord.PCMAudio; return (proc_ytdlp, proc_ffmpeg)
handle.read_all() semua byte sekaligus (hati-hati memori)

URL audio berlaku ± 6 jam dan terikat IP — ambil ulang (get_stream) setiap kali memutar, jangan simpan lama.

🔎 Cara kerja — alur a!p

User : a!p faded
  └─> bot memanggil music.play("a!p faded")
        └─> buang prefix 'a!p'   → 'faded'
        └─> bukan link           → cari di YouTube (ytsearch)
        └─> ambil hasil teratas  → Track {title, author, duration, thumbnail, url}
  └─> bot balas embed (thumbnail + judul + durasi + channel)
  └─> music.get_stream(track) → URL audio → ffmpeg → voice channel

Link dikenali otomatis: YouTube → ambil langsung; Spotify → ambil metadata lalu cocokkan ke YouTube; link lain → error UNSUPPORTED_SOURCE.

📖 API Reference

Musical(strip_prefix=True, default_limit=5, ytdlp_options=None)

Option Default Keterangan
strip_prefix True buang prefix perintah (a!p, !play, bot!p, ...) otomatis
default_limit 5 jumlah hasil default search()
ytdlp_options None opsi yt-dlp tambahan, mis. {"cookiefile": "cookies.txt"}

Metode

Metode Input Return
search(query, limit=None) judul list[Track]
resolve(text) judul / link (boleh berprefix a!p) Track
play(text) sama dengan resolve Track
get_stream(x) Track / judul / link StreamHandle
play_stream(x) Track / judul / link (Track, StreamHandle)
search_async, resolve_async, play_async, get_stream_async, play_stream_async sama coroutine (asyncio)

Fungsi standalone (instance default)

from akuibots_musical import play, resolve, search, get_stream, play_stream
track = play("a!p faded")

Helper

parse_command, strip_command_prefix, is_url, detect_source, format_duration, extract_youtube_id, resolve_spotify — dan MusicalError dengan .code: INVALID_INPUT, NOT_FOUND, SEARCH_FAILED, UNSUPPORTED_SOURCE, SPOTIFY_FAILED, STREAM_FAILED.

🤖 Contoh: Bot Discord (discord.py)

import discord
from discord.ext import commands
from akuibots_musical import Musical

music = Musical()
intents = discord.Intents.default()
intents.message_content = True
bot = commands.Bot(command_prefix="a!", intents=intents)

@bot.event
async def on_ready():
    print("Bot siap:", bot.user)

@bot.command()
async def p(ctx, *, query: str):
    """a!p <judul/link> → play musik di voice channel."""
    if not ctx.author.voice:
        return await ctx.send("Masuk voice channel dulu ya 🎧")
    await ctx.send(f"🔍 Mencari: `{query}`")

    track = await music.play_async(query)          # judul ATAU link
    handle = await music.get_stream_async(track)   # metadata + audio

    if ctx.voice_client is None:
        await ctx.author.voice.channel.connect()

    # ✅ Pola paling awet (2025+): yt-dlp yang mengunduh audionya
    # (headers & PO token diurus yt-dlp), lalu dipipa ke ffmpeg.
    # URL mentah handle.url langsung ke ffmpeg sering DITOLAK YouTube
    # (bot jalan tapi tanpa suara).
    ytdlp_proc, ff_proc = handle.pcm_popen()
    source = discord.PCMAudio(ff_proc.stdout)

    def selesai(e):
        for p in (ytdlp_proc, ff_proc):
            try:
                p.kill()
            except Exception:
                pass
        if e:
            print("FFmpeg error:", e)

    ctx.voice_client.stop()
    ctx.voice_client.play(source, after=selesai)

    embed = discord.Embed(title=track.title, url=track.url, color=0x2B6CB0)
    embed.set_thumbnail(url=track.thumbnail)
    embed.add_field(name="Durasi", value=track.duration_text, inline=True)
    embed.add_field(name="Channel", value=track.author, inline=True)
    embed.set_footer(text=f"Sumber: {track.source}")
    await ctx.send(embed=embed)

bot.run("TOKEN_BOT")

✈️ Contoh: Bot Telegram (python-telegram-bot)

from telegram.ext import Application, CommandHandler, ContextTypes
from telegram import Update
from akuibots_musical import Musical

music = Musical()

async def p(update: Update, context: ContextTypes.DEFAULT_TYPE):
    query = " ".join(context.args or [])
    if not query:
        return await update.message.reply_text("Kirim judul atau link: /p faded")
    msg = await update.message.reply_text(f"🔍 Mencari: {query}")
    track, handle = await music.play_stream_async(query)
    await msg.edit_text(
        f"🎵 {track.title}\n"
        f"👤 {track.author}\n"
        f"⏱ {track.duration_text}\n"
        f"🔗 {track.url}"
    )
    # opsional — kirim file audionya juga:
    # handle.save("lagu.m4a") lalu reply_audio

app = Application.builder().token("TOKEN_BOT").build()
app.add_handler(CommandHandler("p", p))
app.run_polling()

🖥️ Contoh: CLI

#!/usr/bin/env python3
import subprocess, sys
from akuibots_musical import music

track, handle = music.play_stream(" ".join(sys.argv[1:]))
print(f"▶ {track.title} — {track.author}  [{track.duration_text}]")
subprocess.run(["ffplay", "-nodisp", "-autoexit", "-loglevel", "quiet", handle.url])
python player.py "a!p alan walker faded"

⚙️ Opsi yt-dlp & cookies

Semua opsi yt-dlp bisa diteruskan lewat ytdlp_options:

music = Musical(ytdlp_options={
    "cookiefile": "cookies.txt",                       # cookies browser (Netscape)
    "extractor_args": {"youtube": {"player_client": ["ios", "web"]}},
})

🆘 Troubleshooting

Masalah Penyebab & solusi
Sign in to confirm you're not a bot YouTube menandai IP server/VPS. Export cookies.txt dari browser (format Netscape) lalu Musical(ytdlp_options={"cookiefile": "cookies.txt"}). Di IP rumah biasanya langsung jalan.
ffmpeg not found Pasang ffmpeg: apt install ffmpeg / brew install ffmpeg.
URL audio 403 setelah lama URL kadaluarsa (±6 jam) & terikat IP. Panggil get_stream() ulang sebelum tiap memutar.
Bot jalan, embed muncul, tapi tidak ada suara URL audio mentah ditolak YouTube saat diambil ffmpeg langsung (PO token/SABR — aturan baru YouTube 2025+). Solusi: ① pip install -U yt-dlp dan pasang Deno, ② pakai pola pipe handle.pcm_popen() pada contoh Discord (yt-dlp yang mengunduh audionya, bukan ffmpeg), ③ tes dengan script diagnosis di bawah.
SPOTIFY_FAILED Link privat/regional atau diblokir. Coba link track langsung dari aplikasi Spotify (Share → Copy link).
UNSUPPORTED_SOURCE Link bukan YouTube/Spotify. Plugin ini hanya menerima keduanya + judul.
Hasil pencarian kurang pas Beri judul lebih spesifik, mis. a!p alan walker faded bukan a!p faded.

❓ FAQ

Ini bot Discord? Bukan. Ini plugin/library yang dipasang di bot kamu (Discord, Telegram, WhatsApp, CLI, apa saja). Bot yang memproses perintah a!p, plugin ini yang mengerjakan musiknya.

Sama kayak Lavalink? Gak perlu server Lavalink, gak perlu Java, gak perlu API key. Cukup pip install akuibots-musical — pencarian & stream langsung jalan.

Kenapa Spotify cuma dapat metadata? Spotify tidak menyediakan audio untuk pihak ketiga. Plugin mengambil metadata Spotify (judul + artis), lalu otomatis mencocokkannya ke YouTube — jadi music.play_stream(<link spotify>) tetap menghasilkan audio.

Bisa buat download mp3? Bisa — handle.save("lagu.m4a"), atau konversi pakai ffmpeg ke mp3.

Bedanya dengan versi npm?

npm (Node.js) PyPI (Python)
new Musical({...}) Musical(strip_prefix=True, ...)
await music.play(text) music.play(text) / await music.play_async(text)
await music.getStream(x) music.get_stream(x)
track.durationText track.duration_text
Node Readable stream StreamHandle (url, iter_chunks(), save())

Pakai yt-dlp? Ya — mesin pencarian & ekstraksi memakai yt-dlp yang aktif dirawat, jadi jauh lebih tahan perubahan YouTube daripada library ytdl-core lama.

📄 Lisensi

MIT — © 2026 Akuibots. Versi npm: akuibots-musical.

Metadata

Release files for akuibots-musical 1.0.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for akuibots-musical 1.0.1
File Size Uploaded Provenance Actions
akuibots_musical-1.0.1.tar.gz 24.4 kB Without provenance Details for akuibots_musical-1.0.1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for akuibots-musical 1.0.1
File Interpreter ABI Platform Actions
akuibots_musical-1.0.1-py3-none-any.whl Python 3 none any Details for akuibots_musical-1.0.1-py3-none-any.whl

Total release size: 44.7 kB

Release files / akuibots_musical-1.0.1.tar.gz

Download URL akuibots_musical-1.0.1.tar.gz
Size 24.4 kB
Tags Source
SHA-256 checksum
How to use checksums
a59b25d99b136e80237a6f60f13bc478c554ed824e9b6e92d478958de91b64d7
BLAKE2b-256 checksum
How to use checksums
2189fddec60c6c7100f60ef1db98e62583df80c4fe5c5b19cf3772f24c66202b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.16

Release files / akuibots_musical-1.0.1-py3-none-any.whl

Download URL akuibots_musical-1.0.1-py3-none-any.whl
Size 20.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e91023f548bce0a9630c6209558aa9ae6cdd0b341bbe752cabb2519d294d5e87
BLAKE2b-256 checksum
How to use checksums
6793bc5190100f83e76d9ba1255337e7500bd5d02b7e55f8e053c354bc14d724
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.16

Security for akuibots-musical 1.0.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

1.0.1 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page