digital-human-publication.service.ts 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. import { Injectable } from '@angular/core';
  2. import type { GeneratedResult, HistoryRecord, RemixVersion } from '../models/app-shell.model';
  3. export interface DigitalHumanPublicationState {
  4. dhPrompt: string;
  5. dhResolution: string;
  6. }
  7. export interface DigitalHumanPublicationPayload {
  8. result: Partial<GeneratedResult>;
  9. history: Partial<HistoryRecord>;
  10. }
  11. export interface DigitalHumanRemixPublicationInput {
  12. videoTitle: string;
  13. videoId: string;
  14. videoUrl: string;
  15. prompt: string;
  16. resolution: '720p' | '1080p';
  17. durationSeconds: number;
  18. remixId: string;
  19. }
  20. export interface DigitalHumanRemixVersionInput {
  21. videoUrl: string;
  22. thumbnailUrl?: string;
  23. resolution: '720p' | '1080p';
  24. }
  25. @Injectable({ providedIn: 'root' })
  26. export class DigitalHumanPublicationService {
  27. build(videoUrl: string, state: DigitalHumanPublicationState, now = new Date()): DigitalHumanPublicationPayload {
  28. const title = `数字人合成 - ${now.toLocaleString('zh-CN')}`;
  29. const quality = state.dhResolution === '1080p' ? '1080P' : '720P';
  30. return {
  31. result: {
  32. type: 'video',
  33. url: videoUrl,
  34. title,
  35. quality,
  36. duration: '数字人视频',
  37. cost: 0,
  38. segments: [{ id: 'DH-01', videoUrl, prompt: state.dhPrompt, status: 'completed' }],
  39. pipelineId: 'digital_human',
  40. },
  41. history: {
  42. keyword: '数字人合成',
  43. status: 'completed',
  44. cost: 0,
  45. duration: '数字人视频',
  46. styleName: '数字人合成',
  47. resultUrl: videoUrl,
  48. quality,
  49. segmentCount: 1,
  50. successCount: 1,
  51. },
  52. };
  53. }
  54. buildRemix(input: DigitalHumanRemixPublicationInput): DigitalHumanPublicationPayload {
  55. const quality = input.resolution === '1080p' ? '1080P' : '720P';
  56. const duration = input.durationSeconds > 0 ? `${input.durationSeconds} 秒` : '数字人视频';
  57. const cost = Math.round(input.durationSeconds * 100) / 100;
  58. const title = `${input.videoTitle} - 数字人生成`;
  59. return {
  60. result: {
  61. type: 'video',
  62. url: input.videoUrl,
  63. title,
  64. quality,
  65. duration,
  66. cost,
  67. remixId: input.remixId,
  68. videoId: input.videoId,
  69. segments: [{ id: 'DH-01', videoUrl: input.videoUrl, prompt: input.prompt, status: 'completed' }],
  70. pipelineId: 'digital_human',
  71. },
  72. history: {
  73. keyword: title,
  74. original_video_title: input.videoTitle,
  75. status: 'completed',
  76. cost,
  77. duration,
  78. remixId: input.remixId,
  79. videoId: input.videoId,
  80. styleName: '数字人生成',
  81. resultUrl: input.videoUrl,
  82. quality,
  83. segmentCount: 1,
  84. successCount: 1,
  85. },
  86. };
  87. }
  88. buildRemixVersion(input: DigitalHumanRemixVersionInput, now = new Date()): RemixVersion {
  89. return {
  90. id: `REMIX-${Date.now()}`,
  91. style: '数字人生成',
  92. created_at: now,
  93. file_path: input.videoUrl,
  94. thumbnail: input.thumbnailUrl || 'assets/default-remix-thumb.jpg',
  95. description: '使用上传形象图与原视频提取音频生成的数字人版本',
  96. parameters: {
  97. style: 'digital-human',
  98. intensity: 1,
  99. preserve_audio: true,
  100. quality: input.resolution === '1080p' ? 'high' : 'standard',
  101. effects: ['digital-human'],
  102. },
  103. };
  104. }
  105. }