Personal uploader for music‑news recap videos

Ruby News is a local Python tool that uploads finished music‑news videos to TikTok using the official Content Posting API — so you can focus on research and storytelling, not busywork.

Local‑only Manual run Python TikTok Direct Post / Inbox Creates full & shorts Optional YouTube upload
Last updated: 30 October 2025

What it does

  • Authenticates via TikTok OAuth and stores a refreshable token locally.
  • Publishes completed MP4s with a caption (hashtags & mentions supported).
  • Supports Direct Post or Upload to Inbox workflows.
  • Generates both a long video and per‑category short videos.
  • Optional upload of the long video to YouTube.

About Ruby News

Purpose

Summarize the latest music news in short, easy‑to‑digest videos. Ruby News handles the posting so you can stay consistent.

Scope
Personal, single‑account use
Monetization
None
Hosting
Runs locally on the creator’s laptop
Triggers
Manual run (no background daemon)

Tech & API Scopes

  • Language: Python
  • API: TikTok Content Posting API
  • Scopes: video.upload and (if approved) video.publish
  • Media: MP4/H.264 (final renders only)

How it works

1) Fetch & group articles

Fetch today’s music headlines, filter to artist‑centric items, group by category, and enrich categories with additional sources.

2) Build facts → scripts

Create structured facts (who/quotes/timeline/numbers), generate per‑category scripts, then merge, segment, and create a final rundown & script.

3) Render audio & video

Generate voiceover, animate avatar, assemble the news video, add background audio, crop & remove background, and overlay avatar.

Pipeline (from run_job.py)

# 1. News collection & grouping
articles = get_todays_news_by_topic(SEARCH_QUERY_MUSIC)
grouped   = group_articles_by_topic(articles, GROUPING_PROMPT_MUSIC)
with_additional = get_addition_information_for_categories(grouped)

# 2. Facts → scripts → segments → rundown → final script
facts      = create_facts_based_on_articles(articles)
script     = based_on_facts_create_script(facts)
grouped_sc = group_scripts_by_content({category: script, ...})
combined   = create_grouped_scripts(grouped_sc)
segments   = create_segments_for_scripts(combined)
run_down   = create_run_down(segments)
final      = create_full_script(segments, run_down)

# 3. Audio & avatar
generate_voice(final, audio_path)
make_news_anchor_talking_photo_video(mp3=audio_path, save_path=avatar_path)

# 4. Master video assembly
transcript  = transcribe_with_word_timestamps(audio_path)
cue_points  = generate_media_cue_points(segments, run_down)
create_news_video(transcript, cue_points, news_path)
add_background_audio(news_path, with_audio)

# 5. Avatar overlay
crop_height_keep_audio(avatar_path, crop_path)
remove_bg_to_alpha_keep_audio(crop_path, alpha_path)
overlay_avatar_on_video(with_audio, alpha_path, finished_path)

# 6. Publishing
upload_full_video_to_youtube(finished_path, run_down, segments, transcript)   # optional
for category, single_script in combined.items():
    # create per‑category short videos
    create_short_news_video(single_script, transcript, cue_points, out)
    add_background_audio(out, out_with_audio)
    overlay_avatar_on_short_video(single_script, transcript, out_with_audio, alpha_path, base)
    upload_video(short_full_video, single_script)  # TikTok posting

Example console output

$ python run_job.py
Articles fetched: 42
Grouped categories: 6
Total articles in groups: 39
Category: Releases, Articles: 12
Facts who: 18, quotes: 7, timeline: 9, numbers: {"awards": 2}
Script: 1589
...
Collected 6 scripts for full video.
Scripts reduced from 6 to 4
combined scripts
Segments: 28
Run down created.
Final script length : 5623
Audio generated.
Video generated.
Cue points: 120
Transcript created. 7421
News video created.
News video with audio created.
Video cropped.
Background removed. True
Avatar overlayed on video.
Short video for category Releases uploaded.
Short video for category Tours uploaded.
...

(Logs reflect the real pipeline and may vary by day. Replace this with a screenshot or your actual output.)

Privacy, security & data use

Privacy

No personal data from viewers or third parties is collected. The tool only stores a TikTok OAuth token locally to authenticate uploads.

See the Privacy Policy for details.

Security

  • Local‑only operation; no external servers.
  • Tokens kept on device; rotate if compromise is suspected.
  • No analytics, tracking, or data sharing.

FAQ

Is this a public app?

No. Ruby News is a personal tool used by a single TikTok account. It is not sold or offered to others.

Does it generate the videos?

No. Videos are fully produced beforehand (voiceover, avatar, images) using other tools. Ruby News only posts them.

Direct Post vs Inbox?

Direct Post publishes automatically (subject to app approval). Inbox upload sends the video to TikTok’s Inbox for final review in‑app.

What about hashtags and description?

The caption field supports normal text, hashtags (#music), and mentions (@username). There’s no separate tags field.

Contact

Operator: Fabian Westhäußer

Email: ruby.musicnews@gmail.com

TikTok: @RubyMusicNews

Instagram: @RubyMusicNews

YouTube: @RubyMusicNews