360 Secure SkillHub
360 安全技能中心

Xiaoyuzhou Asr

该工具依托本地GPU加速的Qwen3-ASR,结合xyz API获取小宇宙播客数据与音频,实现播客转文字服务。核心功能包括单集/批量转录、播客搜索、音频下载,支持Markdown、SRT、TXT、JSON等多格式输出。典型场景:转录指定单集、批量处理播客最新节目、搜索并转录目标内容。输入支持关键词、节目ID、分享URL、播客ID,所有处理本地化,音频不对外传输,需提前部署xyz API服务器等依赖。

worldwonderer
worldwonderer
热度 47.91
最近更新 2026-05-28 00:26:50
分类:效率依赖:代码执行 / 第三方 API / 读写文件应用场景:API 集成 / 自动化脚本 / 文件转换 / 笔记整理

安装技能

复制下面的话术发给你的 Agent,它会通过 secure-skills 检索并安装该技能。

执行命令安装此 skill: npx secure-skills-cli add xiaoyuzhou-asr
Metadata
name
xiaoyuzhou-asr
description
Transcribe 小宇宙 (Xiaoyuzhou) podcast episodes to text using local Qwen3-ASR speech recognition. Combines xyz API (小宇宙FM API) to fetch episode metadata and audio URLs with qwen3-asr-rs for local GPU-accelerated speech-to-text. Use when user wants to: (1) transcribe a 小宇宙 podcast episode, (2) download podcast audio from 小宇宙, (3) search and transcribe podcast content, (4) batch transcribe multiple episodes. Triggers: 小宇宙, podcast transcription, 播客转文字, ASR, speech recognition, episode transcript, 节目转录, qwen3-asr, 小宇宙转录.

xiaoyuzhou-asr

Transcribe 小宇宙 podcast episodes to text using local Qwen3-ASR (Metal/CUDA accelerated).

Required service: this skill does not call 小宇宙 directly. It requires a compatible ultrazg/xyz API server to be installed and running. Default base URL is http://localhost:23020; override it with XYZ_BASE_URL. Without this service, login, search, episode lookup, and audio URL retrieval will not work.

Prerequisites

  1. xyz API server running — fetches episode data and audio URLs from 小宇宙
    git clone https://github.com/ultrazg/xyz.git && cd xyz && go run .
    # Default port: 23020, change with -p
    
  2. ffmpeg — audio format conversion (brew install ffmpeg)
  3. Qwen3-ASR model — download (HF Hub does NOT ship tokenizer.json):
    python3 -c "
    from huggingface_hub import snapshot_download
    snapshot_download('Qwen/Qwen3-ASR-0.6B', local_dir='models/0.6B')
    "
    
  4. qwen3-asr-rs — build from source:
    git clone https://github.com/alan890104/qwen3-asr-rs.git && cd qwen3-asr-rs
    cargo build --release --example local_transcribe
    
  5. tokenizer.json — auto-generated by the transcription script on first run (from vocab.json + merges.txt). No manual step needed.

Quick Start

# 1. Login (first time only, saves to ~/.xiaoyuzhou-asr.json)
python3 scripts/transcribe_podcast.py --login

# 2. Check all dependencies
python3 scripts/transcribe_podcast.py --check-env

# 3. Transcribe a single episode
python3 scripts/transcribe_podcast.py --keyword "早咖啡" -o output.md

# Or transcribe a shared episode URL
python3 scripts/transcribe_podcast.py --url "https://www.xiaoyuzhoufm.com/episode/EPISODE_ID" -o output.md

CLI Commands

Authentication

# Interactive login — sends verification code to phone, saves tokens
python3 scripts/transcribe_podcast.py --login

Discovery

# Search podcasts and show PID (for batch mode)
python3 scripts/transcribe_podcast.py --podcast-info --keyword "声动早咖啡"

# List recent episodes of a podcast
python3 scripts/transcribe_podcast.py --list-episodes --pid PODCAST_ID --count 10

Transcription

# Single episode by keyword (picks first result)
python3 scripts/transcribe_podcast.py --keyword "关键词" -o output.md

# Single episode by EID
python3 scripts/transcribe_podcast.py --eid EPISODE_ID -o output.md

# Single episode by Xiaoyuzhou URL
python3 scripts/transcribe_podcast.py --url "https://www.xiaoyuzhoufm.com/episode/EPISODE_ID" -o output.md

# Batch: transcribe 5 latest episodes of a podcast
python3 scripts/transcribe_podcast.py --pid PODCAST_ID --count 5 -o ./transcripts/

# With specific format
python3 scripts/transcribe_podcast.py --eid EPISODE_ID --format srt -o output.srt

Diagnostics

# Check all dependencies (ffmpeg, xyz API, token, ASR binary, model)
python3 scripts/transcribe_podcast.py --check-env

Output Formats

Format Flag Description
Markdown --format markdown (default) Metadata header + transcript
SRT --format srt Subtitles with estimated timestamps
Plain text --format txt Minimal header + transcript
JSON --format json Metadata + transcript as JSON

Batch Mode

  • Transcribes the N most recent episodes of a podcast (--pid --count N)
  • Saves each episode as a separate file in the output directory
  • Checkpoint/resume: skips episodes that already exist in the output directory

Configuration

Settings are resolved in priority order: CLI argument > Environment variable > Config file.

Config File (~/.xiaoyuzhou-asr.json)

Auto-created by --login. Can also store paths:

{
  "token": "x-jike-access-token",
  "refresh_token": "x-jike-refresh-token",
  "model_dir": "/path/to/models/0.6B",
  "asr_bin": "/path/to/local_transcribe"
}

Environment Variables

Variable Description Default
XYZ_ACCESS_TOKEN x-jike access token — (required)
XYZ_REFRESH_TOKEN Refresh token for auto-renewal — (optional)
XYZ_BASE_URL xyz API base URL http://localhost:23020
XYZ_HTTP_TIMEOUT xyz API request timeout in seconds 15
XYZ_DOWNLOAD_TIMEOUT Audio download timeout in seconds 120
QWEN3_ASR_MODEL_DIR Qwen3-ASR model directory auto-detect
QWEN3_ASR_BIN local_transcribe binary path auto-detect

Token Management

  • --login saves tokens to config file automatically
  • If API returns 401, auto-refresh using refresh token
  • Prompt user to login if no valid token

References

Constraints

  • MUST split audio into ≤3-minute segments for Metal GPU stability (auto-handled by script)
  • Audio must be WAV 16kHz mono (auto-converted by script)
  • tokenizer.json auto-generated on first run (from vocab.json + merges.txt)
  • xyz API requires Chinese phone number (+86) login
  • All processing is local — audio never leaves the machine
  • Download retries up to 3 times on network failure

Script Reuse

This is a skill project, not a packaged Python library. Prefer the CLI above. Other scripts in this repository can still import scripts/transcribe_podcast.py directly:

from transcribe_podcast import (
    search_episodes, transcribe_episode, format_output,
    TranscriptionError, ApiError, TokenExpiredError,
)

try:
    episodes, _ = search_episodes(token, "早咖啡")
    episode, transcript, timings = transcribe_episode(token, eid, model_dir, asr_bin)
    output = format_output(episode, transcript)
except TranscriptionError as e:
    print(f"Error: {e}")