style: Pint 포맷팅 적용
This commit is contained in:
@@ -35,7 +35,7 @@ public function concatClips(array $clipPaths, string $outputPath): ?string
|
||||
$listContent = '';
|
||||
|
||||
foreach ($clipPaths as $path) {
|
||||
$listContent .= "file " . escapeshellarg($path) . "\n";
|
||||
$listContent .= 'file '.escapeshellarg($path)."\n";
|
||||
}
|
||||
|
||||
file_put_contents($listFile, $listContent);
|
||||
@@ -67,7 +67,7 @@ public function concatClips(array $clipPaths, string $outputPath): ?string
|
||||
$scaledListFile = "{$dir}/scaled_list.txt";
|
||||
$scaledListContent = '';
|
||||
foreach ($scaledPaths as $path) {
|
||||
$scaledListContent .= "file " . escapeshellarg($path) . "\n";
|
||||
$scaledListContent .= 'file '.escapeshellarg($path)."\n";
|
||||
}
|
||||
file_put_contents($scaledListFile, $scaledListContent);
|
||||
|
||||
@@ -151,7 +151,7 @@ public function concatNarrations(array $audioPaths, array $scenes, string $outpu
|
||||
$listFile = "{$dir}/narration_list.txt";
|
||||
$listContent = '';
|
||||
foreach ($paddedPaths as $path) {
|
||||
$listContent .= "file " . escapeshellarg($path) . "\n";
|
||||
$listContent .= 'file '.escapeshellarg($path)."\n";
|
||||
}
|
||||
file_put_contents($listFile, $listContent);
|
||||
|
||||
@@ -209,7 +209,7 @@ public function getAudioDuration(string $path): float
|
||||
* @param array $narrationDurations [scene_number => 실제 오디오 초] (ffprobe 측정값)
|
||||
*/
|
||||
/**
|
||||
* @param string $layout 'portrait' (9:16 Shorts) 또는 'landscape' (16:9 튜토리얼)
|
||||
* @param string $layout 'portrait' (9:16 Shorts) 또는 'landscape' (16:9 튜토리얼)
|
||||
*/
|
||||
public function generateAssSubtitle(array $scenes, string $outputPath, array $narrationDurations = [], string $layout = 'portrait'): string
|
||||
{
|
||||
@@ -306,7 +306,7 @@ public function generateAssSubtitle(array $scenes, string $outputPath, array $na
|
||||
$endTime = $this->formatAssTime($currentTime + $offset + $sentDuration);
|
||||
|
||||
$text = $this->wrapText($sentence, $maxCharsPerLine);
|
||||
$text = str_replace("\n", "\\N", $text);
|
||||
$text = str_replace("\n", '\\N', $text);
|
||||
|
||||
$ass .= "Dialogue: 0,{$startTime},{$endTime},Default,,0,0,0,,{$text}\n";
|
||||
|
||||
@@ -379,7 +379,7 @@ private function splitIntoSentences(string $text): array
|
||||
|
||||
if (mb_strlen($part) < 5 && ! empty($merged)) {
|
||||
// 짧은 조각 → 이전 항목 뒤에 붙임
|
||||
$merged[count($merged) - 1] .= ' ' . $part;
|
||||
$merged[count($merged) - 1] .= ' '.$part;
|
||||
} else {
|
||||
$merged[] = $part;
|
||||
}
|
||||
@@ -403,21 +403,21 @@ public function assemble(
|
||||
mkdir($dir, 0755, true);
|
||||
}
|
||||
|
||||
$inputs = ['-i ' . escapeshellarg($videoPath)];
|
||||
$inputs = ['-i '.escapeshellarg($videoPath)];
|
||||
$filterParts = [];
|
||||
$mapParts = ['-map 0:v'];
|
||||
$audioIndex = 1;
|
||||
|
||||
// 나레이션 추가
|
||||
if ($narrationPath && file_exists($narrationPath)) {
|
||||
$inputs[] = '-i ' . escapeshellarg($narrationPath);
|
||||
$inputs[] = '-i '.escapeshellarg($narrationPath);
|
||||
$filterParts[] = "[{$audioIndex}:a]volume=2.0[nar]";
|
||||
$audioIndex++;
|
||||
}
|
||||
|
||||
// BGM 추가
|
||||
if ($bgmPath && file_exists($bgmPath)) {
|
||||
$inputs[] = '-i ' . escapeshellarg($bgmPath);
|
||||
$inputs[] = '-i '.escapeshellarg($bgmPath);
|
||||
$filterParts[] = "[{$audioIndex}:a]volume=1.2[bgm]";
|
||||
$audioIndex++;
|
||||
}
|
||||
@@ -425,35 +425,35 @@ public function assemble(
|
||||
// 오디오 믹싱 필터
|
||||
if (count($filterParts) === 2) {
|
||||
// 나레이션 + BGM
|
||||
$filterComplex = implode(';', $filterParts) . ';[nar][bgm]amix=inputs=2:duration=first[a]';
|
||||
$filterComplex = implode(';', $filterParts).';[nar][bgm]amix=inputs=2:duration=first[a]';
|
||||
$mapParts[] = '-map "[a]"';
|
||||
} elseif (count($filterParts) === 1) {
|
||||
// 나레이션 또는 BGM 중 하나만
|
||||
$streamName = $narrationPath ? 'nar' : 'bgm';
|
||||
$filterComplex = $filterParts[0];
|
||||
$mapParts[] = '-map "[' . $streamName . ']"';
|
||||
$mapParts[] = '-map "['.$streamName.']"';
|
||||
} else {
|
||||
$filterComplex = null;
|
||||
}
|
||||
|
||||
// FFmpeg 명령 조립
|
||||
$cmd = 'ffmpeg -y ' . implode(' ', $inputs);
|
||||
$cmd = 'ffmpeg -y '.implode(' ', $inputs);
|
||||
|
||||
if ($filterComplex) {
|
||||
$cmd .= ' -filter_complex "' . $filterComplex . '"';
|
||||
$cmd .= ' -filter_complex "'.$filterComplex.'"';
|
||||
}
|
||||
|
||||
$cmd .= ' ' . implode(' ', $mapParts);
|
||||
$cmd .= ' '.implode(' ', $mapParts);
|
||||
|
||||
// 자막 비디오 필터 (슬라이드 캡션바에 텍스트 포함 시 생략 가능)
|
||||
if ($subtitlePath && file_exists($subtitlePath)) {
|
||||
$vf = sprintf("ass=%s", escapeshellarg($subtitlePath));
|
||||
$cmd .= ' -vf ' . escapeshellarg($vf);
|
||||
$vf = sprintf('ass=%s', escapeshellarg($subtitlePath));
|
||||
$cmd .= ' -vf '.escapeshellarg($vf);
|
||||
}
|
||||
$cmd .= ' -c:v libx264 -preset fast -crf 23 -r 30';
|
||||
$cmd .= ' -c:a aac -b:a 192k';
|
||||
$cmd .= ' -shortest';
|
||||
$cmd .= ' ' . escapeshellarg($outputPath);
|
||||
$cmd .= ' '.escapeshellarg($outputPath);
|
||||
$cmd .= ' 2>&1';
|
||||
|
||||
Log::info('VideoAssemblyService: 최종 합성 시작', ['cmd' => $cmd]);
|
||||
@@ -504,11 +504,11 @@ private function wrapText(string $text, int $maxCharsPerLine): string
|
||||
$currentLine = '';
|
||||
|
||||
foreach ($words as $word) {
|
||||
if (mb_strlen($currentLine . ' ' . $word) > $maxCharsPerLine && $currentLine !== '') {
|
||||
if (mb_strlen($currentLine.' '.$word) > $maxCharsPerLine && $currentLine !== '') {
|
||||
$lines[] = trim($currentLine);
|
||||
$currentLine = $word;
|
||||
} else {
|
||||
$currentLine .= ($currentLine ? ' ' : '') . $word;
|
||||
$currentLine .= ($currentLine ? ' ' : '').$word;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user