375 lines
13 KiB
Python
Raw Normal View History

2025-11-12 00:28:07 +08:00
"""
抖音发布示例
演示抖音平台的各种发布场景
"""
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())