You've already forked lubo_comment_query
节目建设页 OCR 侧栏点击填入
This commit is contained in:
@@ -7,6 +7,7 @@ use App\Models\ProgramVideos;
|
||||
use App\Models\VideoComments;
|
||||
use App\Models\VideoParts;
|
||||
use App\Util\ProgramVideoUtil;
|
||||
use App\Util\VideoOcrUtil;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\QueryException;
|
||||
use Illuminate\Http\Request;
|
||||
@@ -60,7 +61,8 @@ class ProgramConstructController extends BaseController
|
||||
|
||||
public function edit(Request $request, Programs $program) {
|
||||
return view("program.construct.create", [
|
||||
"program"=>$program
|
||||
"program"=>$program,
|
||||
"ocr_pivots"=>VideoOcrUtil::panel_pivots($program),
|
||||
]);
|
||||
}
|
||||
// endregion
|
||||
|
||||
@@ -5,6 +5,7 @@ namespace App\Http\Controllers;
|
||||
use App\Models\Programs;
|
||||
use App\Models\ProgramVideos;
|
||||
use App\Util\ProgramVideoUtil;
|
||||
use App\Util\VideoOcrUtil;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Routing\Controller as BaseController;
|
||||
use Illuminate\Support\Carbon;
|
||||
@@ -61,7 +62,8 @@ class ProgramVideoConstructController extends BaseController
|
||||
|
||||
public function edit(Request $request, ProgramVideos $program_video) {
|
||||
return view("program.construct.video.create", [
|
||||
"program_video" => $program_video
|
||||
"program_video" => $program_video,
|
||||
"ocr_pivots" => VideoOcrUtil::panel_pivots($program_video->program),
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
namespace App\Util;
|
||||
|
||||
use App\Models\Programs;
|
||||
use App\Models\ProgramVideos;
|
||||
use App\Models\VideoOcrRecords;
|
||||
use App\Models\VideoParts;
|
||||
use Carbon\Carbon;
|
||||
@@ -198,6 +200,43 @@ class VideoOcrUtil
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 建设页 OCR 面板所需的片段元数据(轻量;帧级重数据由前端按返回的 CDN URL 直接拉取)。
|
||||
* 每个 pivot:id/label/bvid/起止分P与秒/urls(片段范围内有 OCR 的分P → CDN 全量 JSON URL)。
|
||||
* 起止时间未填时对应 sec 为 null(前端不做该侧 in_range 裁剪)。
|
||||
*/
|
||||
public static function panel_pivots(Programs $program): array
|
||||
{
|
||||
$pivots = $program->video_pivots;
|
||||
if ($pivots->isEmpty()) {
|
||||
return [];
|
||||
}
|
||||
$bvids = $pivots->pluck("video_bvid")->unique()->all();
|
||||
$ocrParts = VideoOcrRecords::query()->whereIn("video_bvid", $bvids)
|
||||
->select("video_bvid", "part_num")->distinct()->get()
|
||||
->groupBy("video_bvid")->map(fn($rows) => $rows->pluck("part_num")->map(fn($n) => (int)$n)->all())->all();
|
||||
return $pivots->map(function (ProgramVideos $pivot) use ($ocrParts) {
|
||||
$startPart = (int)$pivot->start_part;
|
||||
$stopPart = (int)$pivot->stop_part;
|
||||
$urls = [];
|
||||
foreach (($ocrParts[$pivot->video_bvid] ?? []) as $partNum) {
|
||||
if ($partNum >= $startPart && $partNum <= $stopPart) {
|
||||
$urls[$partNum] = Storage::url(static::cdn_path($pivot->video_bvid, $partNum));
|
||||
}
|
||||
}
|
||||
return [
|
||||
"id" => $pivot->id,
|
||||
"label" => "{$pivot->video_bvid} P{$pivot->start_part} {$pivot->start_time} → P{$pivot->stop_part} {$pivot->stop_time}",
|
||||
"bvid" => $pivot->video_bvid,
|
||||
"start_part" => $startPart,
|
||||
"start_sec" => $pivot->start_sec === "" ? null : $pivot->start_sec,
|
||||
"stop_part" => $stopPart,
|
||||
"stop_sec" => $pivot->stop_sec === "" ? null : $pivot->stop_sec,
|
||||
"urls" => $urls,
|
||||
];
|
||||
})->values()->all();
|
||||
}
|
||||
|
||||
private static function time_to_seconds($time): ?float
|
||||
{
|
||||
if (is_numeric($time)) {
|
||||
|
||||
Reference in New Issue
Block a user