import os, requests, time, re
YT = os.environ["YOUTUBE_API_KEY"]
MV = os.environ["MAVERA_API_KEY"]
YT_BASE = "https://www.googleapis.com/youtube/v3"
MV_BASE = "https://app.mavera.io/api/v1"
MV_H = {"Authorization": f"Bearer {MV}", "Content-Type": "application/json"}
CHANNEL_ID = "UC_YOUR_CHANNEL_ID"
# 1. Get channel uploads playlist
channel = requests.get(f"{YT_BASE}/channels", params={
"key": YT, "id": CHANNEL_ID,
"part": "contentDetails",
}).json()
uploads_playlist = channel["items"][0]["contentDetails"]["relatedPlaylists"]["uploads"]
# 2. Get recent uploads (1 quota unit per page)
playlist_items = requests.get(f"{YT_BASE}/playlistItems", params={
"key": YT, "playlistId": uploads_playlist,
"part": "snippet", "maxResults": 50,
}).json()
video_ids = [item["snippet"]["resourceId"]["videoId"]
for item in playlist_items.get("items", [])]
# 3. Get full details to classify Shorts vs long-form (1 quota unit)
details = requests.get(f"{YT_BASE}/videos", params={
"key": YT, "id": ",".join(video_ids),
"part": "snippet,contentDetails,statistics",
}).json()
def parse_duration(iso):
match = re.match(r"PT(?:(\d+)H)?(?:(\d+)M)?(?:(\d+)S)?", iso)
if not match:
return 0
h, m, s = (int(g) if g else 0 for g in match.groups())
return h * 3600 + m * 60 + s
shorts = []
long_form = []
for video in details.get("items", []):
duration = parse_duration(video["contentDetails"]["duration"])
stats = video.get("statistics", {})
entry = {
"id": video["id"],
"title": video["snippet"]["title"],
"duration": duration,
"views": int(stats.get("viewCount", 0)),
"likes": int(stats.get("likeCount", 0)),
"comments": int(stats.get("commentCount", 0)),
}
if duration <= 60:
shorts.append(entry)
else:
long_form.append(entry)
print(f"Found {len(shorts)} Shorts, {len(long_form)} long-form videos")
# 4. Analyze top 3 of each format
def analyze_videos(video_list, label):
scored = []
for video in sorted(video_list, key=lambda v: -v["views"])[:3]:
upload = requests.post(f"{MV_BASE}/assets", headers=MV_H, json={
"url": f"https://www.youtube.com/watch?v={video['id']}",
"name": f"[{label}] {video['title'][:40]}", "type": "video",
}).json()
analysis = requests.post(f"{MV_BASE}/video-analysis", headers=MV_H, json={
"asset_id": upload["id"],
"analysis_types": ["hook_score", "emotional_arc", "pacing", "cognitive_load", "visual_complexity"],
}).json()
for _ in range(30):
time.sleep(3)
status = requests.get(
f"{MV_BASE}/video-analysis/{analysis['id']}", headers=MV_H
).json()
if status.get("status") == "completed":
break
r = status.get("results", {})
scored.append({
**video,
"hook": r.get("hook_score", {}).get("score", 0),
"emotion": r.get("emotional_arc", {}).get("intensity_avg", 0),
"pacing": r.get("pacing", {}).get("score", 0),
"cog_load": r.get("cognitive_load", {}).get("average", 0),
})
time.sleep(1)
return scored
shorts_scored = analyze_videos(shorts, "Short")
long_scored = analyze_videos(long_form, "Long")
# 5. Comparison report
def avg_metric(lst, key):
vals = [v[key] for v in lst]
return sum(vals) / len(vals) if vals else 0
print("\nYOUTUBE SHORTS vs. LONG-FORM COMPARISON")
print("=" * 65)
print(f"{'Metric':<25} {'Shorts (avg)':<18} {'Long-Form (avg)':<18} {'Winner'}")
print("-" * 65)
metrics = [
("Views", "views", False),
("Hook Score (/100)", "hook", False),
("Emotional Intensity (/10)", "emotion", False),
("Pacing (/10)", "pacing", False),
("Cognitive Load (/10)", "cog_load", True),
]
for label, key, lower_is_better in metrics:
s_avg = avg_metric(shorts_scored, key)
l_avg = avg_metric(long_scored, key)
winner = "Shorts" if (s_avg < l_avg if lower_is_better else s_avg > l_avg) else "Long-Form"
fmt = ",.0f" if key == "views" else ".1f"
print(f" {label:<25} {s_avg:{fmt}:<18} {l_avg:{fmt}:<18} {winner}")
engagement_short = avg_metric(shorts_scored, "likes") / max(avg_metric(shorts_scored, "views"), 1) * 100
engagement_long = avg_metric(long_scored, "likes") / max(avg_metric(long_scored, "views"), 1) * 100
print(f" {'Engagement Rate':<25} {engagement_short:.2f}%{'':<13} {engagement_long:.2f}%{'':<13} {'Shorts' if engagement_short > engagement_long else 'Long-Form'}")