feat: Add comprehensive timeline editor with frame editing and regeneration capabilities
This commit is contained in:
134
pixelle_video/services/publishing/__init__.py
Normal file
134
pixelle_video/services/publishing/__init__.py
Normal file
@@ -0,0 +1,134 @@
|
||||
# Copyright (C) 2025 AIDC-AI
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
"""
|
||||
Publishing service for multi-platform video distribution.
|
||||
|
||||
Supports:
|
||||
- Format conversion + export (Douyin/Kuaishou)
|
||||
- API-based upload (Bilibili/YouTube)
|
||||
"""
|
||||
|
||||
from abc import ABC, abstractmethod
|
||||
from dataclasses import dataclass, field
|
||||
from enum import Enum
|
||||
from typing import Optional, List, Dict, Any
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
class Platform(Enum):
|
||||
"""Supported publishing platforms"""
|
||||
EXPORT = "export" # Format conversion only
|
||||
DOUYIN = "douyin" # 抖音 (via export or CDP)
|
||||
KUAISHOU = "kuaishou" # 快手 (via export or CDP)
|
||||
BILIBILI = "bilibili" # B站 (API)
|
||||
YOUTUBE = "youtube" # YouTube (API)
|
||||
|
||||
|
||||
class PublishStatus(Enum):
|
||||
"""Publishing task status"""
|
||||
PENDING = "pending"
|
||||
CONVERTING = "converting"
|
||||
UPLOADING = "uploading"
|
||||
PROCESSING = "processing"
|
||||
PUBLISHED = "published"
|
||||
FAILED = "failed"
|
||||
|
||||
|
||||
@dataclass
|
||||
class VideoMetadata:
|
||||
"""Video metadata for publishing"""
|
||||
title: str
|
||||
description: str = ""
|
||||
tags: List[str] = field(default_factory=list)
|
||||
category: Optional[str] = None
|
||||
cover_path: Optional[str] = None
|
||||
privacy: str = "public" # public, private, unlisted
|
||||
|
||||
# Platform-specific options
|
||||
platform_options: Dict[str, Any] = field(default_factory=dict)
|
||||
|
||||
|
||||
@dataclass
|
||||
class PublishResult:
|
||||
"""Result of a publishing operation"""
|
||||
success: bool
|
||||
platform: Platform
|
||||
status: PublishStatus
|
||||
|
||||
# On success
|
||||
video_url: Optional[str] = None
|
||||
platform_video_id: Optional[str] = None
|
||||
|
||||
# On failure
|
||||
error_message: Optional[str] = None
|
||||
|
||||
# Export result
|
||||
export_path: Optional[str] = None
|
||||
|
||||
# Timestamps
|
||||
started_at: Optional[datetime] = None
|
||||
completed_at: Optional[datetime] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class PublishTask:
|
||||
"""A publishing task for background processing"""
|
||||
id: str
|
||||
video_path: str
|
||||
platform: Platform
|
||||
metadata: VideoMetadata
|
||||
status: PublishStatus = PublishStatus.PENDING
|
||||
result: Optional[PublishResult] = None
|
||||
created_at: datetime = field(default_factory=datetime.now)
|
||||
updated_at: Optional[datetime] = None
|
||||
|
||||
|
||||
class Publisher(ABC):
|
||||
"""Abstract base class for platform publishers"""
|
||||
|
||||
platform: Platform
|
||||
|
||||
@abstractmethod
|
||||
async def publish(
|
||||
self,
|
||||
video_path: str,
|
||||
metadata: VideoMetadata,
|
||||
progress_callback: Optional[callable] = None
|
||||
) -> PublishResult:
|
||||
"""
|
||||
Publish a video to the platform.
|
||||
|
||||
Args:
|
||||
video_path: Path to the video file
|
||||
metadata: Video metadata (title, description, tags, etc.)
|
||||
progress_callback: Optional callback for progress updates
|
||||
|
||||
Returns:
|
||||
PublishResult with success/failure details
|
||||
"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
async def validate_credentials(self) -> bool:
|
||||
"""Check if platform credentials are valid"""
|
||||
pass
|
||||
|
||||
def get_platform_requirements(self) -> Dict[str, Any]:
|
||||
"""Get platform-specific requirements (dimensions, file size, etc.)"""
|
||||
return {
|
||||
"max_file_size_mb": 128,
|
||||
"max_duration_seconds": 900, # 15 minutes
|
||||
"supported_formats": ["mp4", "webm"],
|
||||
"recommended_resolution": (1080, 1920), # Portrait 9:16
|
||||
"recommended_codec": "h264",
|
||||
}
|
||||
Reference in New Issue
Block a user