Skip to content

Instantly share code, notes, and snippets.

@nico-lab
Last active October 24, 2022 17:07
Show Gist options
  • Save nico-lab/bff9f88493a86a808913e55d0860b5ef to your computer and use it in GitHub Desktop.
Save nico-lab/bff9f88493a86a808913e55d0860b5ef to your computer and use it in GitHub Desktop.
バンダイチャンネルの字幕を ass に変換する PHP
<?php
/*
http://www.b-ch.com/ttl/caption_list.php 字幕アニメ一覧
// 使い方
php b_ch_sub.php アニメ1話のアドレス 動画の話数指定
php b_ch_sub.php http://www.b-ch.com/ttl/index.php?ttl_c=3463 1
// 未実装
*字幕ファイルに動画タイトルを付ける
*昔の動画の字幕が .vtt なので、それを保存しようとするとエラーになる
http://www.b-ch.com/ttl/index_html5.php?ttl_c=125, 装甲騎兵ボトム
http://flwww.b-ch.com/cmn/live/subttl/webvtt.php?type=F&pv=&ttl=125&stry=1&lang=ja, 字幕ファイルのリンク
他の話数を選択するには stry の値を大きくする
.vtt は ffmpeg で他の字幕フォーマットに変換できる
ffmpeg -i input.vtt output.ass
ffmpeg -i input.vtt output.srt
*/
// 入力値
$u = @$argv[1]; // アニメのアドレス
$id = explode("=", $u);
$series = @$argv[2]; // シリーズの保存話数。2桁まで
// 設定内容
$font = mb_convert_encoding('MS UI Gothic', 'UTF-8', 'sjis-win'); // ass font name
$fsize = 64; // ass font size
$f = 0; // 0 = ass, 1 = srt, 2 = txt
$hallo = 0; // ハロのOPがある場合は8、無ければ0、秒早める。ガンダム系に多い
function a($se, $hallo){ // ass
$hours = floor(($se-$hallo) / 3600);
$minutes = floor((($se-$hallo) / 60) % 60);
$seconds = ($se-$hallo) % 60;
$milli = explode(".", $se);
$hms = sprintf("%1d:%02d:%02d.%02d", $hours, $minutes, $seconds, substr($milli[1],0,2));
return $hms;
}
function s($se, $hallo){ // srt
$hours = floor(($se-$hallo) / 3600);
$minutes = floor((($se-$hallo) / 60) % 60);
$seconds = ($se-$hallo) % 60;
$milli = explode(".", $se);
$hms = sprintf("%02d:%02d:%02d,%03d", $hours, $minutes, $seconds, $milli[1]);
return $hms;
}
for ($j = 1; $j <= $series; $j++){
$ss = sprintf("%02d", $j);
$url = "http://flwww.b-ch.com/cmn/live/subttl/ttl/$id[1]/S_$id[1]_0$ss"."_ja.xml";
$x = file_get_contents($url);
$xml = simplexml_load_string($x);
$subs = ($xml->text->textarea->language->textline);
$c = count($subs); // 字幕数
$path = (parse_url($url, PHP_URL_PATH));
$nxml = explode("/", $path);
$fname = str_replace(".xml", "",$nxml[6]);
switch ($f){
case 0: // ass
$ass = $fname.'.ass';
$fp = fopen($ass, 'w+');
fwrite($fp, '[Script Info]'."\n".'; Script generated by @nico_lab'."\n".'ScriptType: v4.00+'."\n".'PlayResX: 1920'."\n".'PlayResY: 1080'."\n"."\n");
fwrite($fp, '[V4+ Styles]'."\n".'Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding'."\n");
fwrite($fp, 'Style: Default,'.$font.','.$fsize.',&Hffffff,&Hffffff,&H8000ff00,&H0,0,0,0,0,100,100,15,0,1,3,3,2,10,10,30,0'."\n"."\n"); // Style
fwrite($fp, '[Events]'."\n".'Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text'."\n");
for ($i = 0; $i < $c; $i++){
fwrite($fp, 'Dialogue: 0,'.a($subs[$i]['start'], $hallo).','.a($subs[$i]['end'], $hallo).',Default,,0,0,0,,'.str_replace('<br>','\N',$subs[$i])."\n");
}
break;
case 1: // srt
$srt = $fname.'.srt';
$fp = fopen($srt, 'w+');
for ($i = 0; $i < $c; $i++){
fwrite($fp, ($i+1)."\n");
fwrite($fp, s($subs[$i]['start'], $hallo). ' --> '. s($subs[$i]['end'], $hallo). "\n");
fwrite($fp, str_replace('<br>','\N',$subs[$i]). "\n". "\n");
}
break;
case 2: // txt
$txt = $fname.'.txt';
$fp = fopen($txt, 'w+');
foreach ($subs as $sub) {
fwrite($fp, str_replace('<br>',"\n",$sub). "\n");
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment