[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6XDR6Z1PF0YR7J5F5YV9HQX":3,"skill-same:01M6XDR6Z1PF0YR7J5F5YV9HQX":63},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":17,"publishedAt":37,"linkOnly":38,"markdownContent":39,"markdownBody":40,"frontMatter":41,"refName":42,"commitSha":43,"skillDirectory":44,"forksCount":13,"repositoryHtmlUrl":45,"repositoryHomepageUrl":6,"ownerHtmlUrl":46,"ownerBlogUrl":6,"ownerDescription":47,"updatedAt":48,"install":49,"resources":62},"01M6XDR6Z1PF0YR7J5F5YV9HQX","Automatic Speech Recognition (ASR)",null,"Transcribe audio segments to text using Whisper models. Use larger models (small, base, medium, large-v3) for better accuracy, or faster-whisper for optimized performance. Always align transcription timestamps with diarization segments for accurate speaker-labeled subtitles.","Waaaalnut\u002Fskillsbench","Waaaalnut","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F103995656?v=4","01M6XCS9K1V51EY3JMB7DGMX24","01M6XCS9Q4WPW88W62C55G1H44",0,"Apache-2.0","https:\u002F\u002Fgithub.com\u002FWaaaalnut\u002Fskillsbench\u002Fblob\u002Fmain\u002Ftasks-no-skills\u002Fspeaker-diarization-subtitles\u002Fenvironment\u002Fskills\u002Fautomatic-speech-recognition\u002FSKILL.md",[],[18,5,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36],"speech","automatic","recognition","speech recognition","ASR","Audio","text","use","whisper","align","v3","subtitles","with","timestamps","faster-whisper","for","accuracy","transcribe","performance","2026-11-10 10:12:30",false,"---\nname: Automatic Speech Recognition (ASR)\ndescription: Transcribe audio segments to text using Whisper models. Use larger models (small, base, medium, large-v3) for better accuracy, or faster-whisper for optimized performance. Always align transcription timestamps with diarization segments for accurate speaker-labeled subtitles.\n---\n\n# Automatic Speech Recognition (ASR)\n\n## Overview\n\nAfter speaker diarization, you need to transcribe each speech segment to text. Whisper is the current state-of-the-art for ASR, with multiple model sizes offering different trade-offs between accuracy and speed.\n\n## When to Use\n\n- After speaker diarization is complete\n- Need to generate speaker-labeled transcripts\n- Creating subtitles from audio segments\n- Converting speech segments to text\n\n## Whisper Model Selection\n\n### Model Size Comparison\n\n| Model | Size | Speed | Accuracy | Best For |\n|-------|------|-------|----------|----------|\n| tiny | 39M | Fastest | Lowest | Quick testing, low accuracy needs |\n| base | 74M | Fast | Low | Fast processing with moderate accuracy |\n| small | 244M | Medium | Good | **Recommended balance** |\n| medium | 769M | Slow | Very Good | High accuracy needs |\n| large-v3 | 1550M | Slowest | **Best** | **Maximum accuracy** |\n\n### Recommended: Use `small` or `large-v3`\n\n**For best accuracy (recommended for this task):**\n```python\nimport whisper\n\nmodel = whisper.load_model(\"large-v3\")  # Best accuracy\nresult = model.transcribe(audio_path)\n```\n\n**For balanced performance:**\n```python\nimport whisper\n\nmodel = whisper.load_model(\"small\")  # Good balance\nresult = model.transcribe(audio_path)\n```\n\n## Faster-Whisper (Optimized Alternative)\n\nFor faster processing with similar accuracy, use `faster-whisper`:\n\n```python\nfrom faster_whisper import WhisperModel\n\n# Use small model with CPU int8 quantization\nmodel = WhisperModel(\"small\", device=\"cpu\", compute_type=\"int8\")\n\n# Transcribe\nsegments, info = model.transcribe(audio_path, beam_size=5)\n\n# Process segments\nfor segment in segments:\n    print(f\"[{segment.start:.2f}s -> {segment.end:.2f}s] {segment.text}\")\n```\n\n**Advantages:**\n- Faster than standard Whisper\n- Lower memory usage with quantization\n- Similar accuracy to standard Whisper\n\n## Aligning Transcriptions with Diarization Segments\n\nAfter diarization, you need to map Whisper transcriptions to speaker segments:\n\n```python\n# After diarization, you have turns with speaker labels\nturns = [\n    {'start': 0.8, 'duration': 0.86, 'speaker': 'SPEAKER_01'},\n    {'start': 5.34, 'duration': 0.21, 'speaker': 'SPEAKER_01'},\n    # ...\n]\n\n# Run Whisper transcription\nmodel = whisper.load_model(\"large-v3\")\nresult = model.transcribe(audio_path)\n\n# Map transcriptions to turns\ntranscripts = {}\nfor i, turn in enumerate(turns):\n    turn_start = turn['start']\n    turn_end = turn['start'] + turn['duration']\n    \n    # Find overlapping Whisper segments\n    overlapping_text = []\n    for seg in result['segments']:\n        seg_start = seg['start']\n        seg_end = seg['end']\n        \n        # Check if Whisper segment overlaps with diarization turn\n        if seg_start \u003C turn_end and seg_end > turn_start:\n            overlapping_text.append(seg['text'].strip())\n    \n    # Combine overlapping segments\n    transcripts[i] = ' '.join(overlapping_text) if overlapping_text else '[INAUDIBLE]'\n```\n\n## Handling Empty or Inaudible Segments\n\n```python\n# If no transcription found for a segment\nif not overlapping_text:\n    transcripts[i] = '[INAUDIBLE]'\n    \n# Or skip very short segments\nif turn['duration'] \u003C 0.3:\n    transcripts[i] = '[INAUDIBLE]'\n```\n\n## Language Detection\n\nWhisper can auto-detect language, but you can also specify:\n\n```python\n# Auto-detect (recommended)\nresult = model.transcribe(audio_path)\n\n# Or specify language for better accuracy\nresult = model.transcribe(audio_path, language=\"en\")\n```\n\n## Best Practices\n\n1. **Use larger models for better accuracy**: `small` minimum, `large-v3` for best results\n2. **Align timestamps carefully**: Match Whisper segments with diarization turns\n3. **Handle overlaps**: Multiple Whisper segments may overlap with one diarization turn\n4. **Handle gaps**: Some diarization turns may have no corresponding transcription\n5. **Post-process text**: Clean up punctuation, capitalization if needed\n\n## Common Issues\n\n1. **Low transcription accuracy**: Use larger model (small → medium → large-v3)\n2. **Slow processing**: Use faster-whisper or smaller model\n3. **Misaligned timestamps**: Check time alignment between diarization and transcription\n4. **Missing transcriptions**: Check for very short segments or silence\n\n## Integration with Subtitle Generation\n\nAfter transcription, combine with speaker labels for subtitles:\n\n```python\ndef generate_subtitles_ass(turns, transcripts, output_path):\n    # ... header code ...\n    \n    for i, turn in enumerate(turns):\n        start_time = format_time(turn['start'])\n        end_time = format_time(turn['start'] + turn['duration'])\n        speaker = turn['speaker']\n        text = transcripts.get(i, \"[INAUDIBLE]\")\n        \n        # Format: SPEAKER_XX: text\n        f.write(f\"Dialogue: 0,{start_time},{end_time},Default,,0,0,0,,{speaker}: {text}\\n\")\n```\n\n## Performance Tips\n\n1. **For accuracy**: Use `large-v3` model\n2. **For speed**: Use `faster-whisper` with `small` model\n3. **For memory**: Use `faster-whisper` with `int8` quantization\n4. **Batch processing**: Process multiple segments together if possible\n","# Automatic Speech Recognition (ASR)\n\n## Overview\n\nAfter speaker diarization, you need to transcribe each speech segment to text. Whisper is the current state-of-the-art for ASR, with multiple model sizes offering different trade-offs between accuracy and speed.\n\n## When to Use\n\n- After speaker diarization is complete\n- Need to generate speaker-labeled transcripts\n- Creating subtitles from audio segments\n- Converting speech segments to text\n\n## Whisper Model Selection\n\n### Model Size Comparison\n\n| Model | Size | Speed | Accuracy | Best For |\n|-------|------|-------|----------|----------|\n| tiny | 39M | Fastest | Lowest | Quick testing, low accuracy needs |\n| base | 74M | Fast | Low | Fast processing with moderate accuracy |\n| small | 244M | Medium | Good | **Recommended balance** |\n| medium | 769M | Slow | Very Good | High accuracy needs |\n| large-v3 | 1550M | Slowest | **Best** | **Maximum accuracy** |\n\n### Recommended: Use `small` or `large-v3`\n\n**For best accuracy (recommended for this task):**\n```python\nimport whisper\n\nmodel = whisper.load_model(\"large-v3\")  # Best accuracy\nresult = model.transcribe(audio_path)\n```\n\n**For balanced performance:**\n```python\nimport whisper\n\nmodel = whisper.load_model(\"small\")  # Good balance\nresult = model.transcribe(audio_path)\n```\n\n## Faster-Whisper (Optimized Alternative)\n\nFor faster processing with similar accuracy, use `faster-whisper`:\n\n```python\nfrom faster_whisper import WhisperModel\n\n# Use small model with CPU int8 quantization\nmodel = WhisperModel(\"small\", device=\"cpu\", compute_type=\"int8\")\n\n# Transcribe\nsegments, info = model.transcribe(audio_path, beam_size=5)\n\n# Process segments\nfor segment in segments:\n    print(f\"[{segment.start:.2f}s -> {segment.end:.2f}s] {segment.text}\")\n```\n\n**Advantages:**\n- Faster than standard Whisper\n- Lower memory usage with quantization\n- Similar accuracy to standard Whisper\n\n## Aligning Transcriptions with Diarization Segments\n\nAfter diarization, you need to map Whisper transcriptions to speaker segments:\n\n```python\n# After diarization, you have turns with speaker labels\nturns = [\n    {'start': 0.8, 'duration': 0.86, 'speaker': 'SPEAKER_01'},\n    {'start': 5.34, 'duration': 0.21, 'speaker': 'SPEAKER_01'},\n    # ...\n]\n\n# Run Whisper transcription\nmodel = whisper.load_model(\"large-v3\")\nresult = model.transcribe(audio_path)\n\n# Map transcriptions to turns\ntranscripts = {}\nfor i, turn in enumerate(turns):\n    turn_start = turn['start']\n    turn_end = turn['start'] + turn['duration']\n    \n    # Find overlapping Whisper segments\n    overlapping_text = []\n    for seg in result['segments']:\n        seg_start = seg['start']\n        seg_end = seg['end']\n        \n        # Check if Whisper segment overlaps with diarization turn\n        if seg_start \u003C turn_end and seg_end > turn_start:\n            overlapping_text.append(seg['text'].strip())\n    \n    # Combine overlapping segments\n    transcripts[i] = ' '.join(overlapping_text) if overlapping_text else '[INAUDIBLE]'\n```\n\n## Handling Empty or Inaudible Segments\n\n```python\n# If no transcription found for a segment\nif not overlapping_text:\n    transcripts[i] = '[INAUDIBLE]'\n    \n# Or skip very short segments\nif turn['duration'] \u003C 0.3:\n    transcripts[i] = '[INAUDIBLE]'\n```\n\n## Language Detection\n\nWhisper can auto-detect language, but you can also specify:\n\n```python\n# Auto-detect (recommended)\nresult = model.transcribe(audio_path)\n\n# Or specify language for better accuracy\nresult = model.transcribe(audio_path, language=\"en\")\n```\n\n## Best Practices\n\n1. **Use larger models for better accuracy**: `small` minimum, `large-v3` for best results\n2. **Align timestamps carefully**: Match Whisper segments with diarization turns\n3. **Handle overlaps**: Multiple Whisper segments may overlap with one diarization turn\n4. **Handle gaps**: Some diarization turns may have no corresponding transcription\n5. **Post-process text**: Clean up punctuation, capitalization if needed\n\n## Common Issues\n\n1. **Low transcription accuracy**: Use larger model (small → medium → large-v3)\n2. **Slow processing**: Use faster-whisper or smaller model\n3. **Misaligned timestamps**: Check time alignment between diarization and transcription\n4. **Missing transcriptions**: Check for very short segments or silence\n\n## Integration with Subtitle Generation\n\nAfter transcription, combine with speaker labels for subtitles:\n\n```python\ndef generate_subtitles_ass(turns, transcripts, output_path):\n    # ... header code ...\n    \n    for i, turn in enumerate(turns):\n        start_time = format_time(turn['start'])\n        end_time = format_time(turn['start'] + turn['duration'])\n        speaker = turn['speaker']\n        text = transcripts.get(i, \"[INAUDIBLE]\")\n        \n        # Format: SPEAKER_XX: text\n        f.write(f\"Dialogue: 0,{start_time},{end_time},Default,,0,0,0,,{speaker}: {text}\\n\")\n```\n\n## Performance Tips\n\n1. **For accuracy**: Use `large-v3` model\n2. **For speed**: Use `faster-whisper` with `small` model\n3. **For memory**: Use `faster-whisper` with `int8` quantization\n4. **Batch processing**: Process multiple segments together if possible\n",{"name":5,"description":7},"main","7eeb258ada72b7f58119b0e7a2c00ea89d9beedd","tasks-no-skills\u002Fspeaker-diarization-subtitles\u002Fenvironment\u002Fskills\u002Fautomatic-speech-recognition","https:\u002F\u002Fgithub.com\u002FWaaaalnut\u002Fskillsbench","https:\u002F\u002Fgithub.com\u002FWaaaalnut","student of Zhejiang University","2026-04-21 23:16:23",{"source":8,"skillName":5,"commands":50,"prompt":60,"zipAvailable":61},[51,54,57],{"tool":52,"command":53},"npx","npx skills add Waaaalnut\u002Fskillsbench --skill \"Automatic Speech Recognition (ASR)\"",{"tool":55,"command":56},"bunx","bunx skills add Waaaalnut\u002Fskillsbench --skill \"Automatic Speech Recognition (ASR)\"",{"tool":58,"command":59},"pnpm","pnpm dlx skills add Waaaalnut\u002Fskillsbench --skill \"Automatic Speech Recognition (ASR)\"","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002FWaaaalnut\u002Fskillsbench\u002Fblob\u002Fmain\u002Ftasks-no-skills\u002Fspeaker-diarization-subtitles\u002Fenvironment\u002Fskills\u002Fautomatic-speech-recognition\u002FSKILL.md",true,[],[64,78,89,116,137,155],{"skillNo":65,"name":66,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":67,"categories":68,"keywords":74,"publishedAt":37},"01M6XEWMJ6VY3ZC53MPDCPG3GH","data-reconciliation","https:\u002F\u002Fgithub.com\u002FWaaaalnut\u002Fskillsbench\u002Fblob\u002Fmain\u002Ftasks\u002Fxlsx-recover-data\u002Fenvironment\u002Fskills\u002Fdata-reconciliation\u002FSKILL.md",[69],{"categoryNo":70,"categoryName":71,"taxonomyType":72,"taxonomyTypeDesc":73},"01JBSEEDCAT000000000000033","数据分析师","PROFESSION","适用职业",[75,76,77],"data reconciliation","reconciliation","data",{"skillNo":79,"name":80,"nameZh":6,"description":81,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":82,"categories":83,"keywords":84,"publishedAt":37},"01M6XEW8MNPMF1KRXV6ATGFRQF","speech-to-text","Transcribe video to timestamped text using Whisper tiny model (pre-installed).","https:\u002F\u002Fgithub.com\u002FWaaaalnut\u002Fskillsbench\u002Fblob\u002Fmain\u002Ftasks\u002Fvideo-tutorial-indexer\u002Fenvironment\u002Fskills\u002Fspeech-to-text\u002FSKILL.md",[],[18,24,85,86,26,87,88,35],"speech to text","transcribe video","model","Video",{"skillNo":90,"name":91,"nameZh":6,"description":92,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":93,"categories":94,"keywords":100,"publishedAt":37},"01M6XEW3FQZP0T1RKQQJFXVY9T","video-processor","Process videos by removing segments and concatenating remaining parts. Use when you need to remove detected pauses\u002Fopenings from videos, create highlight reels, or batch process segment removals using ffmpeg filter_complex.","https:\u002F\u002Fgithub.com\u002FWaaaalnut\u002Fskillsbench\u002Fblob\u002Fmain\u002Ftasks\u002Fvideo-silence-remover\u002Fenvironment\u002Fskills\u002Fvideo-processor\u002FSKILL.md",[95],{"categoryNo":96,"categoryName":97,"taxonomyType":98,"taxonomyTypeDesc":99},"01JBSEEDCAT000000000000016","图像与多媒体","SCENARIO","使用场景",[88,101,102,103,104,105,106,107,108,109,110,111,112,113,114,25,115],"processor","video processor","batch","create","reels","when","parts","segments","process","videos","you","segment","filter","ffmpeg","remove",{"skillNo":117,"name":118,"nameZh":6,"description":119,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":120,"categories":121,"keywords":123,"publishedAt":37},"01M6XEVXJ5KZ0NTY3XZKRY4AS1","silence-detector","Detect initial silence segments in audio\u002Fvideo using energy-based analysis. Use when you need to find low-energy periods at the start of recordings (title slides, setup time, pre-roll silence).","https:\u002F\u002Fgithub.com\u002FWaaaalnut\u002Fskillsbench\u002Fblob\u002Fmain\u002Ftasks\u002Fvideo-silence-remover\u002Fenvironment\u002Fskills\u002Fsilence-detector\u002FSKILL.md",[122],{"categoryNo":96,"categoryName":97,"taxonomyType":98,"taxonomyTypeDesc":99},[124,125,126,127,106,111,128,129,130,131,132,108,133,23,88,134,135,136,25],"detector","silence detector","title","slides","time","energy","at","recordings","detect","find","analysis","start","setup",{"skillNo":138,"name":139,"nameZh":6,"description":140,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":141,"categories":142,"keywords":143,"publishedAt":37},"01M6XEVT3NGRN1FT7JPMAPXS6M","segment-combiner","Combine multiple segment detection results into a unified list. Use when you need to merge segments from different detectors, prepare removal lists for video processing, or consolidate detection outputs.","https:\u002F\u002Fgithub.com\u002FWaaaalnut\u002Fskillsbench\u002Fblob\u002Fmain\u002Ftasks\u002Fvideo-silence-remover\u002Fenvironment\u002Fskills\u002Fsegment-combiner\u002FSKILL.md",[],[112,144,88,145,146,147,148,33,106,149,150,108,111,151,152,25,153,154],"segment combiner","detection","prepare","merge","video processing","outputs","combine","processing","consolidate","results","list",{"skillNo":156,"name":157,"nameZh":6,"description":158,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":159,"categories":160,"keywords":164,"publishedAt":37},"01M6XEVMPVASGS2KX86QK4FMT7","report-generator","Generate compression reports for video processing. Use when you need to create structured JSON reports with duration statistics, compression ratios, and segment details after video processing.","https:\u002F\u002Fgithub.com\u002FWaaaalnut\u002Fskillsbench\u002Fblob\u002Fmain\u002Ftasks\u002Fvideo-silence-remover\u002Fenvironment\u002Fskills\u002Freport-generator\u002FSKILL.md",[161],{"categoryNo":162,"categoryName":163,"taxonomyType":72,"taxonomyTypeDesc":73},"01JBSEEDCAT000000000000034","行政与办公人员",[165,166,167,112,106,33,111,30,151,168,169,170,25,148,171,88,172,173,104],"generator","report generator","report","statistics","structured","reports","json","compression","generate"]