Lập trình giúp chúng ta thoải mái hơn? (tiếp)
Bài đăng này đã không được cập nhật trong 3 năm
Tình hình là thời gian gần đây download phim trên torrent có vẻ khó khăn hơn rất nhiều, và subtitle tiếng Việt cho mấy phim cũ cũ lại càng ít đi, không hiểu cái thằng subscene nó xóa sub đi làm gì không biết :-s
Sau khi tìm được cái torrent nhiều seed, vất cả cắm máy, xong rồi lên subscene lại thấy không có cái sub nào vừa vặn T.T chỉ muốn đập bàn và hét lên >"< cái thì chậm hơn, cái thì nhanh hơn, cái thì chuẩn timing nhưng lại dịch không chuẩn. haizz, xem bằng sub English cũng được nhưng mà mình có cảm giác phim hay mà không có sub Việt giống như coca không được ướp lạnh mà đã vội vàng cho vào cốc đá ấy, vị không được đậm đà :-s
Ờ thì sub Việt dịch không hay thì vất luôn chứ còn gì, còn cái sub nhanh chậm thì có thể chế biến được. Lượn 1 hồi trên google thì có mấy phần mềm chỉnh sub, đọc đau cả đầu vì nó lằng nhằng quá (hoặc mình quá lười để làm), dùng chính cái MPC thì chỉnh lúc được lúc không, mà cái chính là nội dung cái sub vẫn bị lệch. Hừm, đã thế làm luôn cái tool sync lại cái sub, nhanh gọn trong 1 nốt. Mình thích cái gì cũng 1 nốt cho đời thanh thản.
Cần phải làm gì?
Có vẻ mục đích khá đơn giản, nên chỉ cần:
- Load lại cái sub theo từng dòng.
- Dòng nào quy định thời gian thì cộng hoặc trừ đi thời gian bị lệch.
- Những dòng còn lại giữ nguyên.
Định dạng file sub
Có mấy loại gì đó, đuôi là srt
hay ssa/ass
, chúng ta quan tâm đến cái thằng srt
thôi.
1
00:00:41,010 --> 00:00:43,010
Trans by OmegaQ and Alpha, sync by Alpha.
2
00:00:43,010 --> 00:00:46,100
<i>Hoa Kỳ giờ đây là 1 vùng đất hoang tàn.</i>
3
00:00:47,890 --> 00:00:49,810
<i>Bên trong nó là một thành phố.</i>
4
00:00:51,770 --> 00:00:54,690
<i>Phía ngoài những bức tường ranh giới
là hoang mạc.</i>
5
00:00:54,980 --> 00:00:56,730
<i>Một trái đất bị nguyền rủa.</i>
6
00:00:58,240 --> 00:01:01,570
<i>Bên trong những bức tường
là một thành phố bị nguyền rủa,</i>
7
00:01:01,820 --> 00:01:05,160
<i>trải dài từ Boston tới tận Washington DC.</i>
8
00:01:06,330 --> 00:01:09,000
<i>Một quang cảnh bằng
bê-tông không thể bị phá vỡ.</i>
Chúng ta có thể thấy mỗi 1 lời thoại được quy định bằng 3 dòng
- Số thứ tự
- Thời điểm bắt đầu xuất hiện và thời điểm biến mất
- Nội dung lời thoại
Bắt tay vào làm
public function subtitles()
{
$filename = 'test_sub.srt';
$output = 'sync_sub.srt';
$file = fopen($output, 'wb');
$output = "\xEF\xBB\xBF" . $output;
$lines = file($filename, FILE_IGNORE_NEW_LINES);
$flag = 1;
foreach ($lines as $key => $line) {
$b = mb_convert_encoding($line, 'HTML-ENTITIES', 'UTF-8');
if ((int)$b == $flag) {
$flag++;
fputs($file, $b . "\n");
$a = $key + 1;
$modify = self::changeTime($lines[$key + 1]);
} else {
if ($a == $key) {
fputs($file, $modify . "\n");
} else {
fputs($file, $line . "\n");
}
}
}
fclose($file);
}
Đoạn code trên dùng để load toàn bộ file theo từng dòng. Tưởng đơn giản nhưng có 1 vấn đề xảy ra là bị lỗi UTF-8, loay hoay mãi mới tìm được cách là chuyển định dạng của file sub về UTF-8 và thêm đoạn này vào:
$b = mb_convert_encoding($line, 'HTML-ENTITIES', 'UTF-8');
thì sẽ hết bị lỗi
Rồi, giờ ta sẽ làm thế nào để xác định dòng chứa thời gian. Để ý là dòng thời gian sẽ nằm dưới dòng số thứ tự, thế thì mình làm 1 cái biến flag
, cho chạy từ 1, nếu cái flag đó bằng với dòng chứa số thứ tự thì tăng flag++
và dòng ngay sau đó là dòng chứa thời gian -> lấy ra và chế biến. Những dòng còn lại thì giữ nguyên.
À, cái vấn đề nữa là lúc mình ghi lại ra file output thì lại bị lỗi UTF-8 -_- haizz, tiếng Việt thật là khổ. Ờ nhưng mà không sao, lại mất 1 hồi tìm tòi thì chúng ta chỉ cần thêm dòng
$output = "\xEF\xBB\xBF" . $output;
như phía trên kia là xong thôi, giờ thì chú tâm vào cái hàm changeTime
nữa là xong.
Chỉnh lại thời gian
public function changeTime($time) {
$time = explode(' --> ', $time);
$addTime = 85.995;//second
$time0 = self::addTime($time[0], $addTime);
$time1 = self::addTime($time[1], $addTime);
return implode(' --> ', [$time0, $time1]);
}
Ở trên mình cho thời gian cần thêm vào để sub chạy đúng là 85.995
giây để tăng độ khó cho game :v còn trên thực tế mà cái sub nào bị lệch như thế này thì vất đi chứ giữ lại làm gì :-s
00:00:43,010 --> 00:00:46,100
CHúng ta tách dòng này ra làm 2 mốc thời gian bằng ký tự -->
và cộng thêm cho cả 2 mốc thời gian này 1 khoảng 85.995
giây. Và đó là công việc của thằng addTime()
, mình chỉ có nhiệm vụ tách ra rồi nối lại thôi, không quan tâm tới việc của người khác.
Cộng thêm thời gian
00:00:43,010
Khỉ thật, lằng nhắng phết đấy nhưng mà mình làm xong rồi và viết lại thì thấy đơn giản lắm ) Đại ý là thế này, tách cái thằng trên thành giờ bình thường 00:00:43
và giờ micro giây 0.010
.
Ta tách bằng dấu ,
rồi gán lại cái micro giây bằng dấu .
xong rồi cộng với $addTime
lấy phần dư gán lại vào micro giây này, còn phần thừa cộng tiếp vào cái giờ bình thường kia, chú ý lúc là string lúc là integer, hàm xử lý của nó như thế này:
public function addTime($time, $addTime) {
$explodeTime = explode(',', $time);
$explodeTime[1] = +('0.' . $explodeTime[1]);
$a = $explodeTime[1] + $addTime;
$microTime = $a - floor($a);
$addTime = floor($a);
$normalTime = $explodeTime[0];
$normalTimeArr = explode(':', $normalTime);
$normalSecond = +$normalTimeArr[2] + $addTime;
$normalMinute = +$normalTimeArr[1];
$normalHour = +$normalTimeArr[0];
if ($normalSecond > 59) {
$xxx = (int)($normalSecond / 60);
$normalSecond = $normalSecond - $xxx * 60;
$normalMinute = $normalMinute + $xxx;
if ($normalMinute > 59) {
$xxx = (int)($normalMinute / 60);
$normalMinute = $normalMinute - $xxx * 60;
$normalHour = $normalHour + $xxx;
}
}
$normalTime = implode(':', [
$normalHour < 10 ? '0' . $normalHour : $normalHour,
$normalMinute < 10 ? '0' . $normalMinute : $normalMinute,
$normalSecond < 10 ? '0' . $normalSecond : $normalSecond,
]);
$microTimeArr = explode('.', number_format($microTime, 3));
return $normalTime . ',' . $microTimeArr[1];
}
Có vẻ ghê gớm nhưng thật ra là ghê gớm thật. À, mà ko biết có ai băn khoăn cái đoạn
number_format($microTime, 3);
```
này không nhỉ? Khá là thú vị :D
### Kết quả
Subtile của phim `Dredd` đã được sync lại, chạy nhanh hơn `85.995` giây :-s
![1.JPG](https://images.viblo.asia/70cb76e3-6d73-4b62-8ea7-3836c0fcf0fe.jpg)
## Kết luận
- Hướng dẫn vừa rồi áp dụng cho cộng thêm thời gian cho sub chạy chậm, đối với sub chạy nhanh thì trừ đi thời gian, làm tương tự.
- Thêm form upload file nữa là ngon lành luôn.
- Cuối cùng là thưởng thức bộ phim thôi.:v
All rights reserved