FunAudioLLM

Activity

Stars and mentions · Last 30 days, Oct 6 – Nov 4

GitHub stars0
Mentions2
01234Oct 6Oct 20Nov 4
UTC days · repositories FunAudioLLM owns0 repositories

Top repositories

FunAudioLLM’s repositories ranked by pull request authors, as on trending.

Loading

Contributes to

Repositories outside FunAudioLLM’s account where FunAudioLLM opened or reviewed pull requests in the past 365 days.

Who noticed FunAudioLLM

Everyone who starred or forked FunAudioLLM’s repositories since the archive began in 2011.

Notable accounts

Ordered by the stars their own repositories have received.

Biggest fans

Accounts that starred the most of these repositories.

Breakout weeks

Each repository’s best week of new stars, with the release published around it.

Mentions

2posts
Nov 50 posts
  1. How to Transcribe Douyin (抖音) Videos to Chinese Text Without an API Key Douyin (抖音) doesn't publish subtitles in its web data, so if you want the words spoken in a video you have to run speech recognition yourself. Most open-source Douyin "video to text" projects chain together a video downloader, ffmpeg and a paid speech API (DashScope, SiliconFlow and so on), and they tend to break whenever Douyin changes its cookies. This tutorial shows two ways to get timestamped Chinese transcripts with punctuation without any of that: a no-code run and a few lines of Python. Then a do-it-yourself section on running the speech model on your own machine, with the accuracy comparison I measured between Whisper and SenseVoice on real Douyin narration. Disclosure: I built the Apify actor used in options 1 and 2 (Douyin Transcript Scraper). The DIY section works without it. What you get per video One row per video. Real values from a run on 26 Oct 2026, an 11-minute movie-explainer video (电影解说) by 心影说: | Field | Example | | --- | --- | | url, videoId | https://www.douyin.com/video/7696934197226786058 | | authorNickname | 心影说 | | description | 法律迟迟不肯给出公道,八旬老兵该如何讨回尊严? #伏罗希洛夫射手 #电影解说 | | createdAt | 2026-10-17T09:00:00Z | | durationSeconds | 664.7 | | likeCount, commentCount, shareCount, collectCount | 163, 2, 10, 21 | | language | zh | | characterCount | 4031 | | hook | the opening sentence (segments starting in the first 3 seconds) | | transcript | timed segments [{"start": 0.07, "end": 17.94, "text": "老人架起狙击步枪,…"}] | | musicTitle, audioSource | @心影说创作的原声, original_sound_mp3 | Option 1: No code (Apify Console) 1. Open the actor page and click Try for free. Apify's free plan includes monthly platform credit; the actor itself is pay-per-event (see the Store page for the current price), and videos without speech aren't charged. 2. Paste Douyin videos (douyin.com/video/… links, v.douyin.com/… share links or numeric IDs), or add creators by profile link (douyin.com/user/MS4wLjAB…). 3. Pick the Transcript format: timed segments, plain text or both. 4. Click Start and export the results as CSV, JSON or Excel. For creators, the actor transcribes their newest videos up to Max videos per creator. Douyin shows logged-out visitors roughly the 40 newest videos of an account, so for older videos paste their links directly. Option 2: Python pip install apify-client, then take your API token from Apify Console → Settings → Integrations. from apify_client import ApifyClient client = ApifyClient("<YOUR_APIFY_TOKEN>") run = client.actor("axlymxp/douyin-transcript-scraper").call(run_input={ "videoUrls": ["https://www.douyin.com/video/7696934197226786058"], "profileUrls": [ "https://www.douyin.com/user/MS4wLjABAAAAOzRPcYBhm0xO0mXI5UGjHc2udHifSV-6xuI5mpo_UNKFN6qLVzfWb4QMT8BTOk2n", ], "maxVideosPerProfile": 5, "outputFormat": "both", # segments in `transcript`, joined text in `transcriptText` }) for item in client.dataset(run["defaultDatasetId"]).iterate_items(): if item["error"]: # no_speech, not_available, too_long, ... print("skip", item["videoId"], item["error"]) continue print(item["authorNickname"], item["likeCount"], item["characterCount"], "chars") print(" ", item["transcriptText"][:80]) A natural next step is to feed transcriptText to an LLM for an English summary or translation. Example output One real row (trimmed to two segments; coverUrl removed): { "videoId": "7696934197226786058", "url": "https://www.douyin.com/video/7696934197226786058", "authorNickname": "心影说", "description": "法律迟迟不肯给出公道,八旬老兵该如何讨回尊严? #伏罗希洛夫射手 #电影解说", "createdAt": "2026-10-17T09:00:00Z", "durationSeconds": 664.7, "likeCount": 163, "language": "zh", "audioSource": "original_sound_mp3", "characterCount": 4031, "transcript": [ {"start": 0.07, "end": 17.94, "text": "老人架起狙击步枪,枪口牢牢锁定了对面的三个败类,但一枪爆头的死法显然只会便宜了这几个人渣。他随即调整枪口的角度,对准了坐在正中间的那人。那小子正用双腿夹着香槟酒瓶。就在他拔出瓶塞的瞬间,老人猛的扣下了扳机。"}, {"start": 19.3, "end": 41.44, "text": "玻璃碎片混着鲜血,四下飞溅,不但将现场伪装成了意外爆炸,还顺带废掉了这家伙的作案工具。随后,老人迅速把狙击枪锁进柜子,套上外套,捡起地上的弹壳,神色自若的走下楼,悄无声息的混进了人群之中。…"} ], "error": null } DIY: transcribe Mandarin audio yourself (no API key) If you already have the audio (your own videos, or files you downloaded), you can run a strong Mandarin speech model on a normal CPU. Whisper or SenseVoice? I ran the same 60-second clip of that video's narration through three models on a single cloud vCPU: | Model | Time for 60 s | What came out | | --- | --- | --- | | Whisper base | 11.5 s | Garbled homophones: 扳机 (trigger) became 半斤, 狙击步枪 (sniper rifle) became 嫁起居及不强; traditional and simplified characters mixed | | Whisper small | 37 s | Much better, but in traditional characters, and on another clip it inserted a Korean phrase that nobody said | | SenseVoice-Small | 9.3 s | Simplified Chinese with punctuation; 扳机, 狙击步枪, 神色自若, 悄无声息 all correct | SenseVoice (from Alibaba's FunAudioLLM team) also covers Cantonese, English, Japanese and Korean. The easiest way to run it on CPU is sherpa-onnx: pip install sherpa-onnx av numpy, then download sherpa-onnx-sense-voice-zh-en-ja-ko-yue-2024-07-17.tar.bz2 and silero_vad.onnx from the sherpa-onnx asr-models release. import av, numpy as np, sherpa_onnx SV = "sherpa-onnx-sense-voice-zh-en-ja-ko-yue-2024-07-17" def load_audio(path, rate=16000): """Any audio/video file -> 16 kHz mono float32 (PyAV, no ffmpeg binary needed).""" chunks = [] with av.open(path) as c: rs = av.AudioResampler(format="s16", layout="mono", rate=rate) for frame in c.decode(audio=0): chunks += [f.to_ndarray().reshape(-1) for f in rs.resample(frame)] chunks += [f.to_ndarray().reshape(-1) for f in rs.resample(None)] return np.concatenate(chunks).astype(np.float32) / 32768.0 recognizer = sherpa_onnx.OfflineRecognizer.from_sense_voice( model=f"{SV}/model.int8.onnx", tokens=f"{SV}/tokens.txt", num_threads=1, use_itn=True, language="auto") # use_itn adds punctuation vad_cfg = sherpa_onnx.VadModelConfig() vad_cfg.silero_vad.model = "silero_vad.onnx" vad_cfg.silero_vad.max_speech_duration = 20 # target length; it cuts at the next pause, so some run longer vad_cfg.sample_rate = 16000 vad = sherpa_onnx.VoiceActivityDetector(vad_cfg, buffer_size_in_seconds=60) samples = load_audio("my_video.mp3") window = vad_cfg.silero_vad.window_size segments = [] for i in range(0, len(samples) + window, window): if i < len(samples): vad.accept_waveform(samples[i:i + window]) else: vad.flush() while not vad.empty(): segments.append((vad.front.start / 16000, np.array(vad.front.samples, dtype=np.float32))) vad.pop() for start, seg in segments: # one segment per decode call (see below) stream = recognizer.create_stream() stream.accept_waveform(16000, seg) recognizer.decode_stream(stream) print(f"[{start:7.2f}] {stream.result.text}") Two things that cost me time: - Cut the audio into short segments. On a single 60-second chunk, SenseVoice dropped words in one of three clips. Splitting with voice-activity detection into shorter pieces (most of mine ended up 15-25 seconds) fixed that, and gives you timestamps for free. - Don't batch segments of different lengths. sherpa-onnx can decode a list of streams at once (decode_streams), but the batch is padded to its longest segment. On one vCPU that made transcription about 2.5x slower than decoding one segment at a time: roughly 19 s of CPU per audio minute instead of 7.7 s. Getting the audio out of Douyin is the other half of the job: the video and its download links come from Douyin's signed web API, and the files are big (an 11-minute explainer is 150-210 MB as video). When a video uses the creator's original sound, its audio-only MP3 is much smaller (17-29 MB for 11-17 minutes), which is what the actor downloads. FAQ Do I need a Douyin account? No. Only public videos are read, logged out. Does Douyin provide subtitles? Not in its public web data; every transcript is generated from the audio. How accurate is it? Clear Mandarin narration comes out very well. Background music, dialects, heavy slang or several people talking at once lower accuracy, and song lyrics are transcribed like speech. Traditional characters? SenseVoice outputs simplified Chinese; convert with a library such as OpenCC if you need traditional. Is it legal? These are public videos read without logging in. How you use the transcripts is on you: respect Douyin's terms, copyright and privacy law. Questions or a video that won't work? Open an issue on the actor page and I'll take a look.

  2. 新出的 Fun-ASR-Nano 是 LLM-ASR,SenseVoice 做编码器,Qwen3-0.6B 做解码,支持 7 种中文方言、26 种口音。 现在一条命令就能起 OpenAI 兼容 API,还能挂成 MCP 给 Claude、Cursor 调。 我准备用它做个本地 AI 语音输入法,
🔗 Fun-ASR-Nano:FunAudioLLM/Fun-ASR

    9 views

Achievements

Awards earned by the repositories FunAudioLLM owns. Select an award to embed its badge.

No awards yet

Repositories earn awards by reaching the top three in a completed trending day or week.

A repository earns an award for finishing first, second or third in a completed trending day or week, ranked by new stars, new forks or pull request authors. Awards follow a repository through renames and transfers and count toward its current owner. Weeks run Monday to Sunday, UTC.