Loading...
Loading...
Compare original and translation side by side
~/ai_projects/youtube-uploader/~/ai_projects/my-video/out/agency-swarm-intro.mp4~/.zoom_credentials/ffmpegffprobe~/ai_projects/youtube-uploader/~/ai_projects/my-video/out/agency-swarm-intro.mp4~/.zoom_credentials/ffmpegffprobe1. Identify meeting → 2. Download from Zoom → 3. Add intro/outro
→ 4. Generate timecodes → 5. Write description → 6. Create thumbnail
→ 7. Upload to YouTube → 8. Set thumbnail → 9. Add to playlist1. Identify meeting → 2. Download from Zoom → 3. Add intro/outro
→ 4. Generate timecodes → 5. Write description → 6. Create thumbnail
→ 7. Upload to YouTube → 8. Set thumbnail → 9. Add to playlistpython3 ~/.claude/skills/zoom/scripts/zoom_meetings.py recordings --start YYYY-MM-DDpython3 ~/.claude/skills/zoom/scripts/zoom_meetings.py recording MEETING_IDpython3 ~/.claude/skills/zoom/scripts/zoom_meetings.py recordings --start YYYY-MM-DDpython3 ~/.claude/skills/zoom/scripts/zoom_meetings.py recording MEETING_IDundefinedundefined
**Naming convention:** `YYYYMMDD-meeting-slug.mp4` where slug is a kebab-case topic summary.
**命名规范:** `YYYYMMDD-meeting-slug.mp4`,其中slug是主题摘要的短横线分隔格式。ffprobe -v quiet -print_format json -show_streams INTRO.mp4
ffprobe -v quiet -print_format json -show_streams MEETING.mp4ffprobe -v quiet -print_format json -show_streams INTRO.mp4
ffprobe -v quiet -print_format json -show_streams MEETING.mp4ffmpeg -y -i ~/ai_projects/my-video/out/agency-swarm-intro.mp4 \
-vf "scale=WIDTH:HEIGHT:force_original_aspect_ratio=decrease,pad=WIDTH:HEIGHT:(ow-iw)/2:(oh-ih)/2:black" \
-r FPS -c:v libx264 -preset fast -crf 18 \
-ar SAMPLE_RATE -ac CHANNELS -c:a aac \
/tmp/intro-matched.mp4ffmpeg -y -i ~/ai_projects/my-video/out/agency-swarm-intro.mp4 \
-vf "scale=WIDTH:HEIGHT:force_original_aspect_ratio=decrease,pad=WIDTH:HEIGHT:(ow-iw)/2:(oh-ih)/2:black" \
-r FPS -c:v libx264 -preset fast -crf 18 \
-ar SAMPLE_RATE -ac CHANNELS -c:a aac \
/tmp/intro-matched.mp4ffmpeg -y -ss TRIM_SECONDS -i MEETING.mp4 \
-c:v libx264 -preset fast -crf 18 \
-ar SAMPLE_RATE -ac CHANNELS -c:a aac \
-r FPS -vf "scale=WIDTH:HEIGHT" \
/tmp/meeting-trimmed.mp4ffmpeg -y -ss TRIM_SECONDS -i MEETING.mp4 \
-c:v libx264 -preset fast -crf 18 \
-ar SAMPLE_RATE -ac CHANNELS -c:a aac \
-r FPS -vf "scale=WIDTH:HEIGHT" \
/tmp/meeting-trimmed.mp4echo "file '/tmp/intro-matched.mp4'" > /tmp/concat-list.txt
echo "file '/tmp/meeting-trimmed.mp4'" >> /tmp/concat-list.txtecho "file '/tmp/intro-matched.mp4'" > /tmp/concat-list.txt
echo "file '/tmp/meeting-trimmed.mp4'" >> /tmp/concat-list.txtundefinedundefinedMM:SS Topic descriptionH:MM:SSMM:SS 主题描述H:MM:SSreferences/description-template.mdAGENCY Community Meetup: [Topic]⏱ Таймкоды:AGENCY Community — сообщество практиков AI-автоматизации.#AGENCY #Community/tmp/youtube-description.txtreferences/description-template.mdAGENCY Community Meetup: [Topic]⏱ Таймкоды:AGENCY Community — сообщество практиков AI-автоматизации.#AGENCY #Community/tmp/youtube-description.txt/tmp/thumbnail.htmlreferences/thumbnail-template.htmlSpeaker Name × AGENCYmix-blend-mode: hard-lightreferences/thumbnail-template.html/tmp/thumbnail.htmlSpeaker Name × AGENCYmix-blend-mode: hard-light"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" \
--headless --screenshot=/tmp/thumbnail.png \
--window-size=1280,720 --hide-scrollbars \
"file:///tmp/thumbnail.html"from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch()
page = browser.new_page(viewport={'width': 1280, 'height': 720})
page.goto('file:///tmp/thumbnail.html')
page.wait_for_timeout(2000)
page.screenshot(path='/tmp/thumbnail.png')
browser.close()"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" \
--headless --screenshot=/tmp/thumbnail.png \
--window-size=1280,720 --hide-scrollbars \
"file:///tmp/thumbnail.html"from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch()
page = browser.new_page(viewport={'width': 1280, 'height': 720})
page.goto('file:///tmp/thumbnail.html')
page.wait_for_timeout(2000)
page.screenshot(path='/tmp/thumbnail.png')
browser.close()cd ~/ai_projects/youtube-uploader && python3 youtube_upload.py \
--video ~/ai_projects/my-video/out/FINAL.mp4 \
--title "TITLE" \
--description "$(cat /tmp/youtube-description.txt)" \
--category education \
--privacy public \
--tags "TAG1,TAG2,..." \
--yesTopic — Speaker Namecd ~/ai_projects/youtube-uploader && python3 youtube_upload.py \
--video ~/ai_projects/my-video/out/FINAL.mp4 \
--title "TITLE" \
--description "$(cat /tmp/youtube-description.txt)" \
--category education \
--privacy public \
--tags "TAG1,TAG2,..." \
--yesTopic — Speaker Namecd ~/ai_projects/youtube-uploader && \
python3 youtube_manage.py thumbnails set VIDEO_ID /tmp/thumbnail.pngcd ~/ai_projects/youtube-uploader && \
python3 youtube_manage.py thumbnails set VIDEO_ID /tmp/thumbnail.pngPLZNP0SKU2SqjHOy01UjDxhSRtcluvuw0mcd ~/ai_projects/youtube-uploader && \
python3 youtube_manage.py playlists add-item PLZNP0SKU2SqjHOy01UjDxhSRtcluvuw0m VIDEO_IDPLZNP0SKU2SqjHOy01UjDxhSRtcluvuw0mcd ~/ai_projects/youtube-uploader && \
python3 youtube_manage.py playlists add-item PLZNP0SKU2SqjHOy01UjDxhSRtcluvuw0m VIDEO_ID| Phase | Can parallelize with |
|---|---|
| Download MP4 | Download VTT |
| Re-encode meeting (bg) | Read transcript, draft timecodes |
| Upload to YouTube (bg) | Generate thumbnail |
| Set thumbnail | Add to playlist |
| 阶段 | 可并行操作的环节 |
|---|---|
| 下载MP4 | 下载VTT |
| 重新编码会议录像(后台) | 读取转录文本、草拟时间码 |
| 上传至YouTube(后台) | 生成缩略图 |
| 设置缩略图 | 添加到播放列表 |
https://www.youtube.com/watch?v=VIDEO_IDhttps://studio.youtube.com/video/VIDEO_ID/edithttps://www.youtube.com/watch?v=VIDEO_IDhttps://studio.youtube.com/video/VIDEO_ID/edit~/.claude/skills/zoom/~/.claude/skills/video-youtube-upload/~/.claude/skills/youtube/~/.claude/skills/agency-socials/~/.claude/skills/zoom/~/.claude/skills/video-youtube-upload/~/.claude/skills/youtube/~/.claude/skills/agency-socials/