refactor: Consolidate standalone services into admin-v2, add new SDK modules
Remove standalone services (ai-compliance-sdk root, developer-portal, dsms-gateway, dsms-node, night-scheduler) and legacy compliance/dsgvo pages. Add new SDK pipeline modules (academy, document-crawler, dsb-portal, incidents, whistleblower, reporting, sso, multi-tenant, industry-templates). Add drafting engine, legal corpus files (AT/CH/DE), pitch-deck, blog and Förderantrag pages. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
package academy
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
)
|
||||
|
||||
// VideoGenerator orchestrates video generation with 3-tier fallback:
|
||||
// 1. HeyGen + ElevenLabs -> Avatar video with voice
|
||||
// 2. ElevenLabs only -> Audio podcast style
|
||||
// 3. No external services -> Text + Quiz only
|
||||
type VideoGenerator struct {
|
||||
elevenLabs *ElevenLabsClient
|
||||
heyGen *HeyGenClient
|
||||
}
|
||||
|
||||
// NewVideoGenerator creates a new video generator
|
||||
func NewVideoGenerator() *VideoGenerator {
|
||||
return &VideoGenerator{
|
||||
elevenLabs: NewElevenLabsClient(),
|
||||
heyGen: NewHeyGenClient(),
|
||||
}
|
||||
}
|
||||
|
||||
// GenerationMode describes the available generation mode
|
||||
type GenerationMode string
|
||||
|
||||
const (
|
||||
ModeAvatarVideo GenerationMode = "avatar_video" // HeyGen + ElevenLabs
|
||||
ModeAudioOnly GenerationMode = "audio_only" // ElevenLabs only
|
||||
ModeTextOnly GenerationMode = "text_only" // No external services
|
||||
)
|
||||
|
||||
// GetAvailableMode returns the best available generation mode
|
||||
func (vg *VideoGenerator) GetAvailableMode() GenerationMode {
|
||||
if vg.heyGen.IsConfigured() && vg.elevenLabs.IsConfigured() {
|
||||
return ModeAvatarVideo
|
||||
}
|
||||
if vg.elevenLabs.IsConfigured() {
|
||||
return ModeAudioOnly
|
||||
}
|
||||
return ModeTextOnly
|
||||
}
|
||||
|
||||
// GenerateAudio generates audio from text using ElevenLabs
|
||||
func (vg *VideoGenerator) GenerateAudio(text string) ([]byte, error) {
|
||||
if !vg.elevenLabs.IsConfigured() {
|
||||
return nil, fmt.Errorf("ElevenLabs not configured")
|
||||
}
|
||||
|
||||
log.Printf("Generating audio for text (%d chars)...", len(text))
|
||||
return vg.elevenLabs.TextToSpeech(text)
|
||||
}
|
||||
|
||||
// GenerateVideo generates a video from audio using HeyGen
|
||||
func (vg *VideoGenerator) GenerateVideo(audioURL string) (string, error) {
|
||||
if !vg.heyGen.IsConfigured() {
|
||||
return "", fmt.Errorf("HeyGen not configured")
|
||||
}
|
||||
|
||||
log.Printf("Creating HeyGen video with audio: %s", audioURL)
|
||||
resp, err := vg.heyGen.CreateVideo(audioURL)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return resp.Data.VideoID, nil
|
||||
}
|
||||
|
||||
// CheckVideoStatus checks if a HeyGen video is ready
|
||||
func (vg *VideoGenerator) CheckVideoStatus(videoID string) (string, string, error) {
|
||||
if !vg.heyGen.IsConfigured() {
|
||||
return "", "", fmt.Errorf("HeyGen not configured")
|
||||
}
|
||||
|
||||
status, err := vg.heyGen.GetVideoStatus(videoID)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
|
||||
return status.Data.Status, status.Data.VideoURL, nil
|
||||
}
|
||||
|
||||
// GetStatus returns the configuration status
|
||||
func (vg *VideoGenerator) GetStatus() map[string]interface{} {
|
||||
return map[string]interface{}{
|
||||
"mode": string(vg.GetAvailableMode()),
|
||||
"elevenLabsConfigured": vg.elevenLabs.IsConfigured(),
|
||||
"heyGenConfigured": vg.heyGen.IsConfigured(),
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user