fix: correct Kling API params per official docs
- camera_control: only kling-v1 and kling-v1-5 support it (not v3) - For preset types (down_back etc.), config must be absent — only 'simple' type uses config fields - camera_control and image_tail are mutually exclusive in I2V - cfg_scale not supported by kling-v2.x models — now skipped - duration sent as string to match API examples - v3/v3-omni removed from camera control UI list Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
746cd42f6c
commit
a2358ba01c
2 changed files with 40 additions and 25 deletions
|
|
@ -146,15 +146,20 @@ class KlingAPI {
|
|||
* Text-to-Video generation
|
||||
*/
|
||||
public function textToVideo($prompt, $opts = []) {
|
||||
$modelName = $opts['model_name'] ?? 'kling-v3';
|
||||
$payload = [
|
||||
'prompt' => $prompt,
|
||||
'model_name' => $opts['model_name'] ?? 'kling-v2-6',
|
||||
'mode' => $opts['mode'] ?? 'std',
|
||||
'duration' => intval($opts['duration'] ?? 5),
|
||||
'prompt' => $prompt,
|
||||
'model_name' => $modelName,
|
||||
'mode' => $opts['mode'] ?? 'std',
|
||||
'duration' => strval(intval($opts['duration'] ?? 5)),
|
||||
'aspect_ratio' => $opts['aspect_ratio'] ?? '16:9',
|
||||
'cfg_scale' => floatval($opts['cfg_scale'] ?? 0.5)
|
||||
];
|
||||
|
||||
// cfg_scale not supported by v2.x models
|
||||
if (!preg_match('/^kling-v2/', $modelName)) {
|
||||
$payload['cfg_scale'] = floatval($opts['cfg_scale'] ?? 0.5);
|
||||
}
|
||||
|
||||
if (!empty($opts['negative_prompt'])) {
|
||||
$payload['negative_prompt'] = $opts['negative_prompt'];
|
||||
}
|
||||
|
|
@ -163,14 +168,16 @@ class KlingAPI {
|
|||
$payload['sound'] = 'on';
|
||||
}
|
||||
|
||||
// Camera/motion control — only supported by kling-v1, kling-v1-5, kling-v3, kling-v3-omni
|
||||
$cameraControlModels = ['kling-v1', 'kling-v1-5', 'kling-v3', 'kling-v3-omni'];
|
||||
// camera_control only supported by kling-v1 and kling-v1-5 per capability map
|
||||
if (!empty($opts['camera_control']) && $opts['camera_control'] !== 'none'
|
||||
&& in_array($opts['model_name'] ?? '', $cameraControlModels)) {
|
||||
$payload['camera_control'] = [
|
||||
'type' => $opts['camera_control'],
|
||||
'config' => ['horizontal' => 0, 'vertical' => 0, 'pan' => 0, 'tilt' => 0, 'roll' => 0, 'zoom' => 0]
|
||||
];
|
||||
&& in_array($modelName, ['kling-v1', 'kling-v1-5'])) {
|
||||
$cameraType = $opts['camera_control'];
|
||||
// For preset types, config must be null/absent; only 'simple' type uses config
|
||||
if ($cameraType === 'simple') {
|
||||
$payload['camera_control'] = ['type' => 'simple', 'config' => ['horizontal' => 0, 'vertical' => 0, 'pan' => 0, 'tilt' => 0, 'roll' => 0, 'zoom' => 0]];
|
||||
} else {
|
||||
$payload['camera_control'] = ['type' => $cameraType];
|
||||
}
|
||||
}
|
||||
|
||||
error_log("Kling T2V request: model={$payload['model_name']}, mode={$payload['mode']}, duration={$payload['duration']}");
|
||||
|
|
@ -184,14 +191,19 @@ class KlingAPI {
|
|||
* Image-to-Video generation
|
||||
*/
|
||||
public function imageToVideo($images, $prompt, $opts = []) {
|
||||
$modelName = $opts['model_name'] ?? 'kling-v3';
|
||||
$payload = [
|
||||
'model_name' => $opts['model_name'] ?? 'kling-v2-6',
|
||||
'mode' => $opts['mode'] ?? 'std',
|
||||
'duration' => intval($opts['duration'] ?? 5),
|
||||
'model_name' => $modelName,
|
||||
'mode' => $opts['mode'] ?? 'std',
|
||||
'duration' => strval(intval($opts['duration'] ?? 5)),
|
||||
'aspect_ratio' => $opts['aspect_ratio'] ?? '16:9',
|
||||
'cfg_scale' => floatval($opts['cfg_scale'] ?? 0.5)
|
||||
];
|
||||
|
||||
// cfg_scale not supported by v2.x models
|
||||
if (!preg_match('/^kling-v2/', $modelName)) {
|
||||
$payload['cfg_scale'] = floatval($opts['cfg_scale'] ?? 0.5);
|
||||
}
|
||||
|
||||
if (!empty($prompt)) {
|
||||
$payload['prompt'] = $prompt;
|
||||
}
|
||||
|
|
@ -204,14 +216,17 @@ class KlingAPI {
|
|||
$payload['sound'] = 'on';
|
||||
}
|
||||
|
||||
// Camera/motion control — only supported by kling-v1, kling-v1-5, kling-v3, kling-v3-omni
|
||||
$cameraControlModels = ['kling-v1', 'kling-v1-5', 'kling-v3', 'kling-v3-omni'];
|
||||
// camera_control only for kling-v1/v1-5; also mutually exclusive with image_tail
|
||||
$hasTailFrame = isset($images[1]);
|
||||
if (!empty($opts['camera_control']) && $opts['camera_control'] !== 'none'
|
||||
&& in_array($opts['model_name'] ?? '', $cameraControlModels)) {
|
||||
$payload['camera_control'] = [
|
||||
'type' => $opts['camera_control'],
|
||||
'config' => ['horizontal' => 0, 'vertical' => 0, 'pan' => 0, 'tilt' => 0, 'roll' => 0, 'zoom' => 0]
|
||||
];
|
||||
&& in_array($modelName, ['kling-v1', 'kling-v1-5'])
|
||||
&& !$hasTailFrame) {
|
||||
$cameraType = $opts['camera_control'];
|
||||
if ($cameraType === 'simple') {
|
||||
$payload['camera_control'] = ['type' => 'simple', 'config' => ['horizontal' => 0, 'vertical' => 0, 'pan' => 0, 'tilt' => 0, 'roll' => 0, 'zoom' => 0]];
|
||||
} else {
|
||||
$payload['camera_control'] = ['type' => $cameraType];
|
||||
}
|
||||
}
|
||||
|
||||
// Start frame — field name is `image`, value is clean base64 (no data URI prefix)
|
||||
|
|
|
|||
|
|
@ -240,8 +240,8 @@ const VideoGenTab = ({ activeProjectId, rerunData, onRerunLoaded, onBusyChange,
|
|||
{ value: 'kling-v1-6', label: 'V1.6', description: 'Legacy' },
|
||||
{ value: 'kling-v1', label: 'V1', description: 'Cam control' },
|
||||
];
|
||||
// Models that support camera / motion control
|
||||
const klingCameraControlModels = ['kling-v1', 'kling-v1-5', 'kling-v3', 'kling-v3-omni'];
|
||||
// camera_control presets only supported by kling-v1 and kling-v1-5 per official capability map
|
||||
const klingCameraControlModels = ['kling-v1', 'kling-v1-5'];
|
||||
|
||||
const cameraPresets = [
|
||||
{ value: 'none', label: 'None' },
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue