# [メタ情報]
# 識別子: ダウンロード禁止型動画パッケージphp_exe
# システム名: ダウンロード可能なdynamicに対してダウンロードを禁止するdynamic2を用意。vimeoを使う場合、トランスコードが掛かるため音質が安定しないことが起きる。そのため自作音楽やコピーされたくない動画の配信に使う。
# 技術種別: Misc
# 機能名: Misc
# 使用言語: php
# 状態: 実行用 env終了
# [/メタ情報]
要約:WordPress用の4テンプレ(dr52/dr62/ds52/ds62)。videoct.jsonからdrid一致レコードを取得し、高/低画質と枠内/枠外字幕を切替。rd.phpの到達性をHEADで自動プローブし、優先URLのwpidexからid決定、通常はrd.php経由、不可時は直リンクにフォールバック。診断表示対応。枠内はオーバーレイ字幕でPiP/全画面時はネイティブに切替。枠外は動画下に青字で差分描画し“パカパカ”抑止。字幕一覧・説明文も取得表示。
dr52.php
```
$timeout,
'headers' => ['User-Agent' => 'dr52/1.4'],
]);
if (is_wp_error($res)) return null;
$code = (int) wp_remote_retrieve_response_code($res);
if ($code < 200 || $code >= 300) return null;
$body = wp_remote_retrieve_body($res);
return ($body !== '') ? $body : null;
}
function dr52_fetch_videoct(): ?array {
if (defined('ABSPATH')) {
$json_path = rtrim(ABSPATH, '/') . '/_secure/wp_json/videoct.json';
} else {
$json_path = $_SERVER['DOCUMENT_ROOT'] . '/_secure/wp_json/videoct.json';
}
$body = null;
if (file_exists($json_path)) {
$body = @file_get_contents($json_path);
}
if ($body === false || $body === null) {
$json_url = home_url('/_secure/wp_json/videoct.json');
$body = dr52_http_get($json_url, 12);
}
$data = json_decode($body, true);
return is_array($data) ? $data : null;
}
function dr52_find_video(array $rows, string $drid): ?array {
foreach ($rows as $r) {
if (isset($r['videoid']) && (string)$r['videoid'] === (string)$drid) return $r;
}
return null;
}
function dr52_extract_wpidex_from_url(?string $u): string {
if (!$u) return '';
$p = parse_url($u);
if (!empty($p['query'])) {
parse_str($p['query'], $qs);
if (!empty($qs['id'])) {
$id = (string)$qs['id'];
$id = preg_replace('/\.(mp4|m4v|mov|mp3|m4a|wav|jpg|jpeg|png|gif|webp|vtt|srt|txt)$/i', '', $id);
return $id ?: '';
}
}
$path = $p['path'] ?? '';
if ($path === '') return '';
$base = basename($path);
$id = preg_replace('/\.(mp4|m4v|mov|mp3|m4a|wav|jpg|jpeg|png|gif|webp|vtt|srt|txt|php)$/i', '', $base);
return $id ?: '';
}
function dr52_try_rd(string $id): int {
if ($id === '') return -1;
$rd_abs = rtrim(home_url('/rd.php'), '/');
$url = $rd_abs . '?id=' . rawurlencode($id) . '&mode=dynamic';
$head = wp_remote_head($url, ['timeout'=>8, 'headers'=>['Range'=>'bytes=0-1']]);
if (is_wp_error($head)) return -1;
return (int) wp_remote_retrieve_response_code($head);
}
function dr52_probe_id(array $candidates, array &$diag_log): ?array {
$seen = [];
foreach ($candidates as $cand) {
$cand = trim((string)$cand);
if ($cand === '') continue;
$key = strtolower($cand);
if (isset($seen[$key])) continue;
$seen[$key] = true;
$code = dr52_try_rd($cand);
$diag_log[] = sprintf('probe id="%s" -> %d', $cand, $code);
if ($code >= 200 && $code < 400) return ['id' => $cand, 'code' => $code];
}
return null;
}
/* ========= 本体 ========= */
get_header();
?>
';
if ($original_drid === '') {
echo 'drid が指定されていません。
'; get_footer(); return;
}
$rows = dr52_fetch_videoct();
if (!$rows) {
echo 'JSONデータの取得に失敗しました。(videoct.json)
'; get_footer(); return;
}
$v = dr52_find_video($rows, $current_drid);
if (!$v && $current_drid !== $original_drid) {
$v = dr52_find_video($rows, $original_drid);
if ($v) $current_drid = $original_drid;
}
if (!$v) {
echo '該当IDが見つかりません:' . esc_html($original_drid) . '
'; get_footer(); return;
}
$drid = $current_drid;
$image_url = (string)($v['image'] ?? '');
$video_url = (string)($v['video'] ?? '');
$subtitle_url = (string)($v['subtitle'] ?? '');
$subtitle_list_url = (string)($v['subtitle_list'] ?? '');
$explain_line_url = (string)($v['explain_line'] ?? '');
$rd_abs = rtrim(home_url('/rd.php'), '/');
$diag_log = [];
if ($rid_override !== '') {
$chosen_id = $rid_override;
$chosen_code = dr52_try_rd($chosen_id);
$diag_log[] = sprintf('override id="%s" code=%d', $chosen_id, $chosen_code);
} else {
$cands = [];
$cands[] = dr52_extract_wpidex_from_url($video_url);
$cands[] = dr52_extract_wpidex_from_url($subtitle_url);
$cands[] = dr52_extract_wpidex_from_url($image_url);
$cands[] = $drid;
$more = [];
foreach ($cands as $c) { if (!$c) continue; $more[] = strtolower($c); $more[] = strtoupper($c); }
$cands = array_merge($cands, $more);
$picked = dr52_probe_id($cands, $diag_log);
if ($picked) { $chosen_id = $picked['id']; $chosen_code = $picked['code']; }
else { $chosen_id = ''; $chosen_code = -1; }
}
$stream_src = '';
if ($force_direct && !empty($video_url)) {
$stream_src = $video_url;
} else {
if ($chosen_id !== '') {
$stream_src = $rd_abs . '?id=' . rawurlencode($chosen_id) . '&mode=dynamic';
} else {
$stream_src = $video_url;
}
}
// ★ ここで動画(MP4)か音声(MP3等)かを判定します
$is_audio = preg_match('/\.(mp3|m4a|wav)(?:\?.*)?$/i', $video_url);
?>
';
echo '高画質';
echo '低画質';
echo '|';
echo '枠内字幕';
echo '枠外字幕';
echo '';
echo '';
if (!empty($video_url)) {
if ($is_audio) {
// =========================================
// 音声(MP3)専用の出力(純正コントロールの完全撤廃)
// =========================================
echo '';
if (!empty($image_url)) {
echo '
▶
';
echo '
 . ')
';
}
// ★ controls属性を完全に排除。ブラウザの余計な機能を呼び出さない。
echo '
';
// ★ 手作りのカスタム操作バー(再生ボタンは配置しない)
echo '
';
echo ' 00:00';
echo ' ';
echo ' 00:00';
echo '
';
echo '
';
echo '
';
} else {
// =========================================
// 動画(MP4)専用の完全オリジナル出力
// =========================================
echo '';
echo '
';
echo '
';
echo '
';
}
?>
(この動画の高画質版は準備中です)';
}
echo '';
echo '';
if (!empty($subtitle_list_url)) {
echo '';
$html = dr52_http_get($subtitle_list_url, 10);
echo $html ? $html : '
字幕一覧の取得に失敗しました。
';
echo '
';
?>
';
if (strpos($txt, '<') !== false && strpos($txt, '>') !== false) {
echo wp_kses_post($txt);
} else {
echo '' . nl2br(esc_html($txt)) . '
';
}
echo '';
}
}
echo '';
if (have_posts()) : while (have_posts()) : the_post();
echo '';
the_content();
echo '
';
endwhile; endif;
get_footer();
?>
```
dr62.php
```
$timeout,
'headers' => ['User-Agent' => 'dr62/1.4'],
]);
if (is_wp_error($res)) return null;
$code = (int) wp_remote_retrieve_response_code($res);
if ($code < 200 || $code >= 300) return null;
$body = wp_remote_retrieve_body($res);
return ($body !== '') ? $body : null;
}
function dr62_fetch_videoct(): ?array {
if (defined('ABSPATH')) {
$json_path = rtrim(ABSPATH, '/') . '/_secure/wp_json/videoct.json';
} else {
$json_path = $_SERVER['DOCUMENT_ROOT'] . '/_secure/wp_json/videoct.json';
}
$body = null;
if (file_exists($json_path)) {
$body = @file_get_contents($json_path);
}
if ($body === false || $body === null) {
$json_url = home_url('/_secure/wp_json/videoct.json');
$body = dr62_http_get($json_url, 12);
}
$data = json_decode($body, true);
return is_array($data) ? $data : null;
}
function dr62_find_video(array $rows, string $drid): ?array {
foreach ($rows as $r) {
if (isset($r['videoid']) && (string)$r['videoid'] === (string)$drid) return $r;
}
return null;
}
function dr62_extract_wpidex_from_url(?string $u): string {
if (!$u) return '';
$p = parse_url($u);
if (!empty($p['query'])) {
parse_str($p['query'], $qs);
if (!empty($qs['id'])) {
$id = (string)$qs['id'];
$id = preg_replace('/\.(mp4|m4v|mov|mp3|m4a|wav|jpg|jpeg|png|gif|webp|vtt|srt|txt)$/i', '', $id);
return $id ?: '';
}
}
$path = $p['path'] ?? '';
if ($path === '') return '';
$base = basename($path);
$id = preg_replace('/\.(mp4|m4v|mov|mp3|m4a|wav|jpg|jpeg|png|gif|webp|vtt|srt|txt|php)$/i', '', $base);
return $id ?: '';
}
function dr62_try_rd(string $id): int {
if ($id === '') return -1;
$rd_abs = rtrim(home_url('/rd.php'), '/');
$url = $rd_abs . '?id=' . rawurlencode($id) . '&mode=dynamic';
$head = wp_remote_head($url, ['timeout'=>8, 'headers'=>['Range'=>'bytes=0-1']]);
if (is_wp_error($head)) return -1;
return (int) wp_remote_retrieve_response_code($head);
}
function dr62_probe_id(array $candidates, array &$diag_log): ?array {
$seen = [];
foreach ($candidates as $cand) {
$cand = trim((string)$cand);
if ($cand === '') continue;
$key = strtolower($cand);
if (isset($seen[$key])) continue;
$seen[$key] = true;
$code = dr62_try_rd($cand);
$diag_log[] = sprintf('probe id="%s" -> %d', $cand, $code);
if ($code >= 200 && $code < 400) return ['id' => $cand, 'code' => $code];
}
return null;
}
/* ========= 本体 ========= */
get_header();
?>
';
if ($drid === '') {
echo 'drid が指定されていません。(例:?drid=XXXX)
';
echo ''; get_footer(); return;
}
$rows = dr62_fetch_videoct();
if (!$rows) {
echo 'JSONデータの取得に失敗しました。(videoct.json)
';
echo ''; get_footer(); return;
}
$v = dr62_find_video($rows, $drid);
if (!$v) {
echo '該当IDが見つかりません:' . esc_html($drid) . '
';
echo ''; get_footer(); return;
}
$image_url = (string)($v['image'] ?? '');
$video_url = (string)($v['video'] ?? '');
$video2_url = (string)($v['video2'] ?? '');
$subtitle_url = (string)($v['subtitle'] ?? '');
$subtitle_list_url = (string)($v['subtitle_list'] ?? '');
$explain_line_url = (string)($v['explain_line'] ?? '');
$rd_abs = rtrim(home_url('/rd.php'), '/');
$diag_log = [];
if ($rid_override !== '') {
$chosen_id = $rid_override;
$chosen_code = dr62_try_rd($chosen_id);
$diag_log[] = sprintf('override id="%s" code=%d', $chosen_id, $chosen_code);
} else {
$cands = [];
$cands[] = dr62_extract_wpidex_from_url($video2_url);
$cands[] = dr62_extract_wpidex_from_url($subtitle_url);
$cands[] = dr62_extract_wpidex_from_url($image_url);
$cands[] = $drid;
$more = [];
foreach ($cands as $c) { if (!$c) continue; $more[] = strtolower($c); $more[] = strtoupper($c); }
$cands = array_merge($cands, $more);
$picked = dr62_probe_id($cands, $diag_log);
if ($picked) { $chosen_id = $picked['id']; $chosen_code = $picked['code']; }
else { $chosen_id = ''; $chosen_code = -1; }
}
$stream_src = '';
if ($force_direct && !empty($video2_url)) {
$stream_src = $video2_url;
$diag_log[] = 'force_direct=1 → stream_src = direct low-quality URL';
} else {
if ($chosen_id !== '') {
$stream_src = $rd_abs . '?id=' . rawurlencode($chosen_id) . '&mode=dynamic';
$diag_log[] = 'stream_src via rd.php (mode=dynamic)';
} else {
$stream_src = $video2_url;
$diag_log[] = 'chosen_id empty → fallback to direct low-quality URL';
}
}
if ($diag) {
echo '診断(dr62)
';
$diag_txt = "drid={$drid}\nvideo2_url={$video2_url}\nsubtitle_url={$subtitle_url}\nimage_url={$image_url}\nchosen_id={$chosen_id}\nchosen_code={$chosen_code}\nforce_direct=" . ($force_direct ? '1' : '0') . "\nstream_src={$stream_src}\n--- probe log ---\n".implode("\n", $diag_log)."\n";
echo esc_html($diag_txt);
echo " ";
$head = wp_remote_head($stream_src, ['timeout'=>8,'headers'=>['Range'=>'bytes=0-1']]);
$code = is_wp_error($head) ? -1 : (int)wp_remote_retrieve_response_code($head);
$href = esc_url(add_query_arg('diag','1',$stream_src));
echo '';
}
?>
';
echo '高画質';
echo '低画質';
echo '|';
echo '枠内字幕';
echo '枠外字幕';
echo '';
echo '';
if (!empty($video2_url)) {
echo '';
echo '
';
echo '
';
echo '
';
?>
(この動画の低画質版は準備中です)';
}
echo '';
echo '';
if (!empty($subtitle_list_url)) {
echo '';
$html = dr62_http_get($subtitle_list_url, 10);
echo $html ? $html : '
字幕一覧の取得に失敗しました。
';
echo '
';
?>
';
if (strpos($txt, '<') !== false && strpos($txt, '>') !== false) {
echo wp_kses_post($txt);
} else {
echo '' . nl2br(esc_html($txt)) . '
';
}
echo '';
}
}
echo '';
if (have_posts()) : while (have_posts()) : the_post();
echo '';
the_content();
echo '
';
endwhile; endif;
get_footer();
?>
```
ds52.php
```
$timeout,
'headers' => ['User-Agent' => 'ds52/1.4'],
]);
if (is_wp_error($res)) return null;
$code = (int) wp_remote_retrieve_response_code($res);
if ($code < 200 || $code >= 300) return null;
$body = wp_remote_retrieve_body($res);
return ($body !== '') ? $body : null;
}
function ds52_fetch_videoct(): ?array {
if (defined('ABSPATH')) {
$json_path = rtrim(ABSPATH, '/') . '/_secure/wp_json/videoct.json';
} else {
$json_path = $_SERVER['DOCUMENT_ROOT'] . '/_secure/wp_json/videoct.json';
}
$body = null;
if (file_exists($json_path)) {
$body = @file_get_contents($json_path);
}
if ($body === false || $body === null) {
$json_url = home_url('/_secure/wp_json/videoct.json');
$body = ds52_http_get($json_url, 12);
}
$data = json_decode($body, true);
return is_array($data) ? $data : null;
}
function ds52_find_video(array $rows, string $drid): ?array {
foreach ($rows as $r) {
if (isset($r['videoid']) && (string)$r['videoid'] === (string)$drid) return $r;
}
return null;
}
/** URL→wpidex 抽出(rd.php?id=... / 直リンク両対応) */
function ds52_extract_wpidex_from_url(?string $u): string {
if (!$u) return '';
$p = parse_url($u);
if (!empty($p['query'])) {
parse_str($p['query'], $qs);
if (!empty($qs['id'])) {
$id = (string)$qs['id'];
$id = preg_replace('/\.(mp4|m4v|mov|mp3|m4a|wav|jpg|jpeg|png|gif|webp|vtt|srt|txt)$/i', '', $id);
return $id ?: '';
}
}
$path = $p['path'] ?? '';
if ($path === '') return '';
$base = basename($path);
$id = preg_replace('/\.(mp4|m4v|mov|mp3|m4a|wav|jpg|jpeg|png|gif|webp|vtt|srt|txt|php)$/i', '', $base);
return $id ?: '';
}
/* rd.php へのHEADで到達性チェック(200/206/302ならOK) */
function ds52_try_rd(string $id): int {
if ($id === '') return -1;
$rd_abs = rtrim(home_url('/rd.php'), '/');
$url = $rd_abs . '?id=' . rawurlencode($id) . '&mode=dynamic';
$head = wp_remote_head($url, ['timeout'=>8, 'headers'=>['Range'=>'bytes=0-1']]);
if (is_wp_error($head)) return -1;
return (int) wp_remote_retrieve_response_code($head);
}
/* 候補IDを順に試し、最初に2xx/3xxのidを返す */
function ds52_probe_id(array $candidates, array &$diag_log): ?array {
$seen = [];
foreach ($candidates as $cand) {
$cand = trim((string)$cand);
if ($cand === '') continue;
$key = strtolower($cand);
if (isset($seen[$key])) continue;
$seen[$key] = true;
$code = ds52_try_rd($cand);
$diag_log[] = sprintf('probe id="%s" -> %d', $cand, $code);
if ($code >= 200 && $code < 400) return ['id' => $cand, 'code' => $code];
}
return null;
}
/* ========= 本体 ========= */
get_header();
?>
';
if ($drid === '') {
echo 'drid が指定されていません。(例:?drid=XXXX)
';
echo ''; get_footer(); return;
}
$rows = ds52_fetch_videoct();
if (!$rows) {
echo 'JSONデータの取得に失敗しました。(videoct.json)
';
echo ''; get_footer(); return;
}
$v = ds52_find_video($rows, $drid);
if (!$v) {
echo '該当IDが見つかりません:' . esc_html($drid) . '
';
echo ''; get_footer(); return;
}
$image_url = (string)($v['image'] ?? '');
$video_url = (string)($v['video'] ?? ''); // ★高画質(使用)
$video2_url = (string)($v['video2'] ?? ''); // 低画質(リンク先で使用)
$subtitle_url = (string)($v['subtitle'] ?? '');
/* ====== rd.phpに渡す id を自動決定(高画質優先) ====== */
$rd_abs = rtrim(home_url('/rd.php'), '/');
$diag_log = [];
if ($rid_override !== '') {
$chosen_id = $rid_override;
$chosen_code = ds52_try_rd($chosen_id);
$diag_log[] = sprintf('override id="%s" code=%d', $chosen_id, $chosen_code);
} else {
$cands = [];
$cands[] = ds52_extract_wpidex_from_url($video_url); // 高画質を最優先
$cands[] = ds52_extract_wpidex_from_url($subtitle_url);
$cands[] = ds52_extract_wpidex_from_url($image_url);
$cands[] = $drid; // 保険
$more = [];
foreach ($cands as $c) { if (!$c) continue; $more[] = strtolower($c); $more[] = strtoupper($c); }
$cands = array_merge($cands, $more);
$picked = ds52_probe_id($cands, $diag_log);
if ($picked) { $chosen_id = $picked['id']; $chosen_code = $picked['code']; }
else { $chosen_id = ''; $chosen_code = -1; }
}
/* 再生ソース決定:通常は rd.php(dynamic)/?force=direct=1 なら直リンク(video) */
$stream_src = '';
if ($force_direct && !empty($video_url)) {
$stream_src = $video_url; // 直リンク
$diag_log[] = 'force_direct=1 → stream_src = direct high-quality URL';
} else {
if ($chosen_id !== '') {
$stream_src = $rd_abs . '?id=' . rawurlencode($chosen_id) . '&mode=dynamic';
$diag_log[] = 'stream_src via rd.php (mode=dynamic)';
} else {
$stream_src = $video_url; // 黒画面回避の保険
$diag_log[] = 'chosen_id empty → fallback to direct high-quality URL';
}
}
/* ====== スタイル(dr52/dr62と統一) ====== */
?>
';
echo ' 高画質 ';
echo ' 低画質';
echo ' |';
echo ' 枠内字幕';
echo ' 枠外字幕';
echo '';
/* ====== 診断(必要時のみ) ====== */
if ($diag) {
echo '診断(ds52)
';
$diag_txt =
"drid={$drid}\n".
"video_url={$video_url}\n".
"subtitle_url={$subtitle_url}\n".
"image_url={$image_url}\n".
"chosen_id={$chosen_id}\n".
"chosen_code={$chosen_code}\n".
"force_direct=" . ($force_direct ? '1' : '0') . "\n".
"stream_src={$stream_src}\n".
"--- probe log ---\n".implode("\n", $diag_log)."\n";
echo esc_html($diag_txt);
echo " ";
$head = wp_remote_head($stream_src, ['timeout'=>8,'headers'=>['Range'=>'bytes=0-1']]);
$code = is_wp_error($head) ? -1 : (int)wp_remote_retrieve_response_code($head);
$href = esc_url(add_query_arg('diag','1',$stream_src));
echo '';
}
/* ====== 動画(枠外字幕:ネイティブ字幕は非表示にして下に描画) ====== */
echo '';
echo ' ';
echo ' ';
echo '';
/* ====== 枠外字幕(動画と同じ幅) ====== */
echo '';
/* ====== JS:cuechangeのみ差分描画(翻訳の“パカパカ”抑止) ====== */
?>
';
the_content();
echo '';
endwhile; endif;
echo ''; // .ds5-shell
get_footer();
?>
```
ds62.php
```
$timeout,
'headers' => ['User-Agent' => 'ds62/1.4'],
]);
if (is_wp_error($res)) return null;
$code = (int) wp_remote_retrieve_response_code($res);
if ($code < 200 || $code >= 300) return null;
$body = wp_remote_retrieve_body($res);
return ($body !== '') ? $body : null;
}
function ds62_fetch_videoct(): ?array {
if (defined('ABSPATH')) {
$json_path = rtrim(ABSPATH, '/') . '/_secure/wp_json/videoct.json';
} else {
$json_path = $_SERVER['DOCUMENT_ROOT'] . '/_secure/wp_json/videoct.json';
}
$body = null;
if (file_exists($json_path)) {
$body = @file_get_contents($json_path);
}
if ($body === false || $body === null) {
$json_url = home_url('/_secure/wp_json/videoct.json');
$body = ds62_http_get($json_url, 12);
}
$data = json_decode($body, true);
return is_array($data) ? $data : null;
}
function ds62_find_video(array $rows, string $drid): ?array {
foreach ($rows as $r) {
if (isset($r['videoid']) && (string)$r['videoid'] === (string)$drid) return $r;
}
return null;
}
/** URL→wpidex 抽出(rd.php?id=... / 直リンク両対応) */
function ds62_extract_wpidex_from_url(?string $u): string {
if (!$u) return '';
$p = parse_url($u);
if (!empty($p['query'])) {
parse_str($p['query'], $qs);
if (!empty($qs['id'])) {
$id = (string)$qs['id'];
$id = preg_replace('/\.(mp4|m4v|mov|mp3|m4a|wav|jpg|jpeg|png|gif|webp|vtt|srt|txt)$/i', '', $id);
return $id ?: '';
}
}
$path = $p['path'] ?? '';
if ($path === '') return '';
$base = basename($path);
$id = preg_replace('/\.(mp4|m4v|mov|mp3|m4a|wav|jpg|jpeg|png|gif|webp|vtt|srt|txt|php)$/i', '', $base);
return $id ?: '';
}
/* rd.php へのHEADで到達性チェック(200/206/302ならOK) */
function ds62_try_rd(string $id): int {
if ($id === '') return -1;
$rd_abs = rtrim(home_url('/rd.php'), '/');
$url = $rd_abs . '?id=' . rawurlencode($id) . '&mode=dynamic';
$head = wp_remote_head($url, ['timeout'=>8, 'headers'=>['Range'=>'bytes=0-1']]);
if (is_wp_error($head)) return -1;
return (int) wp_remote_retrieve_response_code($head);
}
/* 候補IDを順に試し、最初に2xx/3xxのidを返す */
function ds62_probe_id(array $candidates, array &$diag_log): ?array {
$seen = [];
foreach ($candidates as $cand) {
$cand = trim((string)$cand);
if ($cand === '') continue;
$key = strtolower($cand);
if (isset($seen[$key])) continue;
$seen[$key] = true;
$code = ds62_try_rd($cand);
$diag_log[] = sprintf('probe id="%s" -> %d', $cand, $code);
if ($code >= 200 && $code < 400) return ['id' => $cand, 'code' => $code];
}
return null;
}
/* ========= 本体 ========= */
get_header();
?>
';
if ($drid === '') {
echo 'drid が指定されていません。(例:?drid=XXXX)
';
echo ''; get_footer(); return;
}
$rows = ds62_fetch_videoct();
if (!$rows) {
echo 'JSONデータの取得に失敗しました。(videoct.json)
';
echo ''; get_footer(); return;
}
$v = ds62_find_video($rows, $drid);
if (!$v) {
echo '該当IDが見つかりません:' . esc_html($drid) . '
';
echo ''; get_footer(); return;
}
$image_url = (string)($v['image'] ?? '');
$video_url = (string)($v['video'] ?? ''); // 高画質(リンク先で利用)
$video2_url = (string)($v['video2'] ?? ''); // ★低画質(使用)
$subtitle_url = (string)($v['subtitle'] ?? '');
/* ====== rd.phpに渡す id を自動決定(低画質優先) ====== */
$rd_abs = rtrim(home_url('/rd.php'), '/');
$diag_log = [];
if ($rid_override !== '') {
$chosen_id = $rid_override;
$chosen_code = ds62_try_rd($chosen_id);
$diag_log[] = sprintf('override id="%s" code=%d', $chosen_id, $chosen_code);
} else {
$cands = [];
$cands[] = ds62_extract_wpidex_from_url($video2_url); // ★低画質を最優先
$cands[] = ds62_extract_wpidex_from_url($subtitle_url);
$cands[] = ds62_extract_wpidex_from_url($image_url);
$cands[] = $drid; // 保険
$more = [];
foreach ($cands as $c) { if (!$c) continue; $more[] = strtolower($c); $more[] = strtoupper($c); }
$cands = array_merge($cands, $more);
$picked = ds62_probe_id($cands, $diag_log);
if ($picked) { $chosen_id = $picked['id']; $chosen_code = $picked['code']; }
else { $chosen_id = ''; $chosen_code = -1; }
}
/* 再生ソース決定:通常は rd.php(dynamic)/?force=direct=1 なら直リンク(video2) */
$stream_src = '';
if ($force_direct && !empty($video2_url)) {
$stream_src = $video2_url; // 直リンク
$diag_log[] = 'force_direct=1 → stream_src = direct low-quality URL';
} else {
if ($chosen_id !== '') {
$stream_src = $rd_abs . '?id=' . rawurlencode($chosen_id) . '&mode=dynamic';
$diag_log[] = 'stream_src via rd.php (mode=dynamic)';
} else {
$stream_src = $video2_url; // 黒画面回避の保険
$diag_log[] = 'chosen_id empty → fallback to direct low-quality URL';
}
}
/* ====== スタイル(dr52/dr62/ds52と統一) ====== */
?>
';
echo ' 高画質';
echo ' 低画質';
echo ' |';
echo ' 枠内字幕';
echo ' 枠外字幕';
echo '';
/* ====== 診断(必要時のみ) ====== */
if ($diag) {
echo '診断(ds62)
';
$diag_txt =
"drid={$drid}\n".
"video_url={$video_url}\n".
"video2_url={$video2_url}\n".
"subtitle_url={$subtitle_url}\n".
"image_url={$image_url}\n".
"chosen_id={$chosen_id}\n".
"chosen_code={$chosen_code}\n".
"force_direct=" . ($force_direct ? '1' : '0') . "\n".
"stream_src={$stream_src}\n".
"--- probe log ---\n".implode("\n", $diag_log)."\n";
echo esc_html($diag_txt);
echo " ";
$head = wp_remote_head($stream_src, ['timeout'=>8,'headers'=>['Range'=>'bytes=0-1']]);
$code = is_wp_error($head) ? -1 : (int)wp_remote_retrieve_response_code($head);
$href = esc_url(add_query_arg('diag','1',$stream_src));
echo '';
}
/* ====== 動画(枠外字幕:ネイティブ字幕は非表示にして下に描画) ====== */
echo '';
echo ' ';
echo ' ';
echo '';
/* ====== 枠外字幕(動画と同じ幅) ====== */
echo '';
/* ====== JS:cuechangeのみ差分描画(翻訳の“パカパカ”抑止) ====== */
?>
';
the_content();
echo '';
endwhile; endif;
echo ''; // .ds6-shell
get_footer();
?>
```
dr52emd.php
```
10,
'headers' => ['User-Agent' => 'dr52emd/1.4'],
]);
if (is_wp_error($res)) {
// file_get_contents によるセーフフォールバック
$body = @file_get_contents($url);
return ($body !== false && $body !== '') ? $body : null;
}
$code = (int) wp_remote_retrieve_response_code($res);
if ($code < 200 || $code >= 300) {
$body = @file_get_contents($url);
return ($body !== false && $body !== '') ? $body : null;
}
$body = wp_remote_retrieve_body($res);
return ($body !== '') ? $body : null;
}
$is_fragment = (isset($_GET['frag']) && $_GET['frag'] == '1');
if (!$is_fragment) { get_header(); }
$drid = get_dropbox_data();
if ($drid && function_exists('get_alt_video_id')) { $drid = get_alt_video_id($drid); }
if ($drid) {
// 【物理パス優先直読み化:videoct.json】
if (defined('ABSPATH')) {
$json_path = rtrim(ABSPATH, '/') . '/_secure/wp_json/videoct.json';
} else {
$json_path = $_SERVER['DOCUMENT_ROOT'] . '/_secure/wp_json/videoct.json';
}
$json_data = null;
if (file_exists($json_path)) {
$json_data = @file_get_contents($json_path);
}
if ($json_data === false || $json_data === null) {
$json_url = home_url('/_secure/wp_json/videoct.json');
$json_data = dr52emd_http_get($json_url);
}
if ($json_data !== false && $json_data !== null) {
$videos = json_decode($json_data, true);
$v = null;
foreach($videos as $row){
if((string)$row['videoid'] === (string)$drid){ $v = $row; break; }
}
if ($v) {
$image_url = $v['image'] ?? '';
$video_url = $v['video'] ?? '';
$subtitle_url = $v['subtitle'] ?? '';
$subtitle_list_url = $v['subtitle_list'] ?? '';
$is_audio = preg_match('/\.(mp3|m4a|wav)(?:\?.*)?$/i', $video_url);
// ---- Styles ----
echo '';
echo '';
if ($is_audio) {
echo '
';
if(!empty($image_url)) {
echo '
▶
';
echo '
.')
';
}
echo '
';
echo '
00:00
00:00
';
echo '
';
} else {
echo '
';
echo '';
echo '
';
}
if (!empty($subtitle_list_url)) {
// 【物理パス優先直読み化:字幕一覧HTML】
$sub_html = dr52emd_http_get($subtitle_list_url);
echo '
' . ($sub_html ? $sub_html : '
字幕一覧の取得に失敗しました。
') . '
';
}
echo '
'; // .dr5emd-container
?>
```