2025-11-12 00:28:07 +08:00

375 lines
13 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
抖音发布示例
演示抖音平台的各种发布场景。
"""
import asyncio
import sys
from pathlib import Path
# 添加项目根目录到Python路径
project_root = Path(__file__).parent.parent
sys.path.insert(0, str(project_root))
from core.publisher import Publisher
from core.models import VideoContent, PlatformType, AccountInfo
from utils.logger import setup_logger, get_logger
# 设置日志
setup_logger(level="INFO")
logger = get_logger(__name__)
async def douyin_video_publish_example():
"""抖音视频发布示例"""
print("=" * 60)
print("抖音视频发布示例")
print("=" * 60)
async with Publisher(headless=False) as publisher:
# 设置账号
account_name = "your_douyin_account" # 替换为实际账号名
print(f"1. 设置抖音账号: {account_name}")
success = await publisher.setup_platform("douyin", account_name)
if not success:
print("❌ 账号设置失败,请检查网络和账号信息")
return
print("✅ 账号设置成功")
# 创建多种类型的视频内容
videos = [
# 娱乐搞笑视频
VideoContent(
title="😂 今日最佳搞笑时刻",
description="收集了一些超级搞笑的瞬间,保证让你笑出声!记得点赞关注哦~ #搞笑 #日常 #娱乐",
video_path="media/videos/funny_moments.mp4", # 替换为实际视频路径
tags=["搞笑", "日常", "娱乐", "短视频"]
),
# 生活技巧视频
VideoContent(
title="🔥 超实用生活技巧分享",
description="分享5个超级实用的生活小技巧让你的生活更加便利。学会了记得分享给朋友哦#生活技巧 #实用 #分享",
video_path="media/videos/life_hacks.mp4", # 替换为实际视频路径
tags=["生活技巧", "实用", "分享", "教程"]
),
# 美食制作视频
VideoContent(
title="🍜 10分钟搞定一碗美味面条",
description="忙碌工作日也能吃到美食今天分享一个超简单的面条做法10分钟就能搞定味道还不错哦#美食 #教程 #快手菜",
video_path="media/videos/quick_noodles.mp4", # 替换为实际视频路径
tags=["美食", "教程", "快手菜", "面条"]
),
# 健身运动视频
VideoContent(
title="💪 居家健身5分钟燃脂训练",
description="不需要任何器械在家就能做的燃脂训练每天坚持5分钟让你拥有好身材。#健身 #燃脂 #运动",
video_path="media/videos/home_workout.mp4", # 替换为实际视频路径
tags=["健身", "燃脂", "运动", "居家"]
)
]
# 发布视频
for i, video in enumerate(videos, 1):
print(f"\n{i}. 发布视频: {video.title}")
try:
result = await publisher.publish("douyin", video, account_name)
if result.success:
print(f"✅ 发布成功!")
print(f" 任务ID: {result.task_id}")
print(f" 耗时: {result.duration:.2f}")
if result.published_url:
print(f" 链接: {result.published_url}")
else:
print(f"❌ 发布失败: {result.message}")
if result.error_details:
print(f" 错误详情: {result.error_details}")
except Exception as e:
print(f"❌ 发布异常: {e}")
# 发布间隔(避免频繁操作)
if i < len(videos):
wait_time = 15 + (i * 5) # 递增等待时间
print(f"⏳ 等待{wait_time}秒后发布下一个视频...")
await asyncio.sleep(wait_time)
async def douyin_batch_upload_example():
"""抖音批量上传示例"""
print("=" * 60)
print("抖音批量上传示例")
print("=" * 60)
# 批量准备视频内容
video_contents = [
VideoContent(
title=f"批量测试视频 {i+1}",
description=f"这是第{i+1}个批量上传的测试视频,内容为{i+1}",
video_path=f"media/videos/batch_test_{i+1}.mp4", # 替换为实际视频路径
tags=[f"批量测试{i+1}", "自动化", "测试"]
)
for i in range(3)
]
async with Publisher(headless=False) as publisher:
# 设置账号
account_name = "your_douyin_account" # 替换为实际账号名
success = await publisher.setup_platform("douyin", account_name)
if not success:
print("❌ 账号设置失败")
return
print("✅ 账号设置成功")
print(f"开始批量上传 {len(video_contents)} 个视频...")
# 创建发布任务
from core.models import PublishTask
tasks = []
for i, content in enumerate(video_contents):
task = PublishTask(
id=f"douyin_batch_{i+1}",
platform=PlatformType.DOUYIN,
account=AccountInfo(
platform=PlatformType.DOUYIN,
username=account_name,
cookie_file=f"{account_name}.json"
),
content=content,
max_retries=2 # 设置重试次数
)
tasks.append(task)
# 执行批量上传
try:
results = await publisher.batch_publish(tasks)
# 统计结果
success_count = sum(1 for r in results if r.success)
print(f"\n📊 批量上传完成:")
print(f" 成功: {success_count}/{len(results)}")
print(f" 失败: {len(results) - success_count}/{len(results)}")
# 详细结果
for result in results:
status = "" if result.success else ""
duration = f" ({result.duration:.1f}s)" if result.duration else ""
print(f" {status} {result.task_id}: {result.message}{duration}")
except Exception as e:
print(f"❌ 批量上传异常: {e}")
async def douyin_upload_with_progress_example():
"""抖音上传进度监控示例"""
print("=" * 60)
print("抖音上传进度监控示例")
print("=" * 60)
async with Publisher(headless=False) as publisher:
# 设置账号
account_name = "your_douyin_account" # 替换为实际账号名
success = await publisher.setup_platform("douyin", account_name)
if not success:
print("❌ 账号设置失败")
return
print("✅ 账号设置成功")
# 创建一个较大的视频文件用于测试进度监控
video = VideoContent(
title="上传进度测试视频 📊",
description="这是一个用于测试上传进度监控功能的视频,文件比较大,可以清楚地看到上传进度。",
video_path="media/videos/large_video.mp4", # 替换为实际的大视频路径
tags=["测试", "上传", "进度监控"]
)
print(f"\n开始上传视频: {video.title}")
print("注意:这会打开浏览器窗口,你可以看到实际的上传过程")
try:
result = await publisher.publish("douyin", video, account_name)
if result.success:
print(f"✅ 视频上传成功!")
print(f" 任务ID: {result.task_id}")
print(f" 总耗时: {result.duration:.2f}")
else:
print(f"❌ 视频上传失败: {result.message}")
except Exception as e:
print(f"❌ 上传异常: {e}")
async def douyin_content_validation_example():
"""抖音内容验证示例"""
print("=" * 60)
print("抖音内容验证示例")
print("=" * 60)
async with Publisher() as publisher:
# 测试各种内容验证场景
test_cases = [
# 有效内容
{
"name": "有效的视频内容",
"content": VideoContent(
title="有效标题",
description="有效描述",
video_path="test.mp4"
),
"expected": True
},
# 无效内容 - 空标题
{
"name": "空标题",
"content": VideoContent(
title="",
description="有效描述",
video_path="test.mp4"
),
"expected": False
},
# 无效内容 - 空描述
{
"name": "空描述",
"content": VideoContent(
title="有效标题",
description="",
video_path="test.mp4"
),
"expected": False
},
# 无效内容 - 不支持的格式
{
"name": "不支持的文件格式",
"content": VideoContent(
title="有效标题",
description="有效描述",
video_path="test.avi" # 假设不支持avi格式
),
"expected": False
},
# 无效内容 - 视频时长过长
{
"name": "视频时长过长",
"content": VideoContent(
title="有效标题",
description="有效描述",
video_path="test.mp4",
duration=1200 # 20分钟假设平台限制为10分钟
),
"expected": False
}
]
print("开始内容验证测试...")
for i, test_case in enumerate(test_cases, 1):
print(f"\n{i}. 测试: {test_case['name']}")
try:
is_valid, error_msg = await publisher.validate_content(
"douyin",
test_case['content']
)
if is_valid == test_case['expected']:
print(f" ✅ 验证结果符合预期")
else:
print(f" ❌ 验证结果不符合预期")
print(f" 期望: {test_case['expected']}")
print(f" 实际: {is_valid}")
if not is_valid:
print(f" 错误信息: {error_msg}")
except Exception as e:
print(f" ❌ 验证异常: {e}")
async def douyin_quick_publish_example():
"""抖音快速发布示例"""
print("=" * 60)
print("抖音快速发布示例")
print("=" * 60)
try:
from core.publisher import publish_to_douyin
# 快速发布单个视频
print("1. 使用快速发布功能...")
result = await publish_to_douyin(
title="🎬 快速发布测试视频",
description="这是使用快速发布功能上传的测试视频,简单方便!#快速发布 #测试 #自动化",
video_path="media/videos/quick_test.mp4", # 替换为实际视频路径
tags=["快速发布", "测试", "自动化"],
account_name="your_douyin_account", # 替换为实际账号名
headless=False
)
if result.success:
print(f"✅ 快速发布成功!")
print(f" 任务ID: {result.task_id}")
print(f" 耗时: {result.duration:.2f}")
else:
print(f"❌ 快速发布失败: {result.message}")
except Exception as e:
print(f"❌ 快速发布异常: {e}")
async def main():
"""主函数"""
print("🚀 抖音发布示例")
print("=" * 60)
print("请确保:")
print("1. 替换示例中的账号名称")
print("2. 准备好视频文件")
print("3. 确保网络连接正常")
print("4. 视频文件格式符合要求mp4、mov等")
print("=" * 60)
try:
# 运行示例
print("选择要运行的示例:")
print("1. 视频发布")
print("2. 批量上传")
print("3. 上传进度监控")
print("4. 内容验证")
print("5. 快速发布")
choice = input("\n请输入选择 (1-5): ").strip()
if choice == "1":
await douyin_video_publish_example()
elif choice == "2":
await douyin_batch_upload_example()
elif choice == "3":
await douyin_upload_with_progress_example()
elif choice == "4":
await douyin_content_validation_example()
elif choice == "5":
await douyin_quick_publish_example()
else:
print("❌ 无效选择")
except KeyboardInterrupt:
print("\n⏹️ 用户中断")
except Exception as e:
print(f"\n❌ 运行异常: {e}")
import traceback
traceback.print_exc()
if __name__ == "__main__":
asyncio.run(main())