中英字幕合并 qt写的
python的修改版字幕合并随着装系统而丢了,就用qt又写一遍。。
SubtitlesMerger.pro
1 #------------------------------------------------- 2 # 3 # Project created by QtCreator 2012-04-14T15:32:10 4 # 5 #------------------------------------------------- 6 7 QT += core gui 8 9 TARGET = SubtitlesMerger 10 TEMPLATE = app 11 12 TRANSLATIONS += SubtitlesMerger_zh_CN.ts 13 14 15 SOURCES += main.cpp\ 16 mainwindow.cpp 17 18 HEADERS += mainwindow.h
main.cpp
1 #include <QtGui/QApplication> 2 #include <QTranslator> 3 #include "mainwindow.h" 4 5 int main(int argc, char *argv[]) 6 { 7 QApplication a(argc, argv); 8 9 QTranslator t; 10 t.load("SubtitlesMerger_zh_CN"); 11 a.installTranslator(&t); 12 13 MainWindow w; 14 w.show(); 15 16 return a.exec(); 17 }
mainwindow.h
1 #ifndef MAINWINDOW_H 2 #define MAINWINDOW_H 3 4 #include <QtGui/QMainWindow> 5 6 class QAction; 7 class QPlainTextEdit; 8 class QDir; 9 10 struct Session 11 { 12 int timeStart; 13 int timeEnd; 14 QString str; 15 QString timeString() 16 { 17 int a[8]; 18 int *p = a; 19 20 *(p++) = (int) this->timeStart / 3600000; 21 *(p++) = (int) (this->timeStart % 3600000) / 60000; 22 *(p++) = (int) (this->timeStart % 60000) / 1000; 23 *(p++) = this->timeStart % 1000; 24 25 *(p++) = (int) this->timeEnd / 3600000; 26 *(p++) = (int) (this->timeEnd % 3600000) / 60000; 27 *(p++) = (int) (this->timeEnd % 60000) / 1000; 28 *(p++) = this->timeEnd % 1000; 29 return QString().sprintf("%02d:%02d:%02d,%03d --> %02d:%02d:%02d,%03d", a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7]); 30 } 31 }; 32 33 class MainWindow : public QMainWindow 34 { 35 Q_OBJECT 36 37 public: 38 MainWindow(QWidget *parent = 0); 39 ~MainWindow(); 40 41 private slots: 42 void dirActionTriggered(); 43 void mergeActionTriggered(); 44 45 private: 46 QList<Session *> getSessions(const QString &f); 47 48 QAction *dirAction; 49 QAction *mergeAction; 50 QPlainTextEdit *edit; 51 }; 52 53 #endif // MAINWINDOW_H
mainwindow.cpp
1 #include "mainwindow.h" 2 3 #include <QtCore> 4 #include <QtGui> 5 6 MainWindow::MainWindow(QWidget *parent) 7 : QMainWindow(parent) 8 { 9 resize(500, 300); 10 setWindowTitle(tr("SubtitlesMerger")); 11 12 dirAction = menuBar()->addAction(tr("&Dir")); 13 connect(dirAction, SIGNAL(triggered()), this, SLOT(dirActionTriggered())); 14 15 mergeAction = menuBar()->addAction(tr("&Merge")); 16 connect(mergeAction, SIGNAL(triggered()), this, SLOT(mergeActionTriggered())); 17 18 edit = new QPlainTextEdit; 19 edit->setFont(QFont("Courier New", 10)); 20 edit->setReadOnly(true); 21 setCentralWidget(edit); 22 } 23 24 MainWindow::~MainWindow() 25 { 26 } 27 28 void MainWindow::dirActionTriggered() 29 { 30 QString s = QFileDialog::getExistingDirectory(this, tr("Select Directory"), 31 ".", QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks); 32 33 if (s.isNull()) 34 return; 35 36 edit->appendPlainText(tr("setting directory to %1").arg(s)); 37 QDir::setCurrent(s); 38 } 39 40 void MainWindow::mergeActionTriggered() 41 { 42 QDir dir("."); 43 44 QStringList sl; 45 sl << "*.chs.srt"; 46 QStringList ss = dir.entryList(sl); 47 48 foreach (QString s, ss) 49 { 50 QString s0 = s.mid(0, s.length() - 8); 51 QString s2 = s0 + ".eng.srt"; 52 if (!dir.exists(s2)) 53 { 54 edit->appendPlainText(tr("dir invalid")); 55 continue; 56 } 57 58 edit->appendPlainText(tr("processing %1").arg(s0)); 59 QList<Session *> ses1 = getSessions(s); 60 QList<Session *> ses2 = getSessions(s2); 61 62 QFile out(s0 + ".all.srt"); 63 if (!out.open(QIODevice::WriteOnly | QIODevice::Text)) 64 { 65 edit->appendPlainText(tr("output error in %1").arg(s0)); 66 continue; 67 } 68 69 QTextStream outs(&out); 70 outs.setCodec("GBK"); 71 72 int i = 0; 73 while (!ses1.isEmpty() && !ses2.isEmpty()) 74 { 75 Session *se1 = ses1.first(); 76 Session *se2 = ses2.first(); 77 78 if (se1->timeStart == se2->timeStart && se1->timeEnd == se2->timeEnd) 79 { 80 outs << ++i << "\n"; 81 outs << se1->timeString() << "\n"; 82 outs << se1->str << "\n"; 83 outs << se2->str << "\n"; 84 outs << "\n"; 85 86 ses1.removeFirst(); 87 ses2.removeFirst(); 88 } 89 else if (se1->timeEnd < se2->timeStart) 90 { 91 outs << ++i << "\n"; 92 outs << se1->timeString() << "\n"; 93 outs << se1->str << "\n"; 94 outs << "\n"; 95 96 ses1.removeFirst(); 97 } 98 else if (se1->timeStart > se2->timeEnd) 99 { 100 outs << ++i << "\n"; 101 outs << se2->timeString() << "\n"; 102 outs << se2->str << "\n"; 103 outs << "\n"; 104 105 ses2.removeFirst(); 106 } 107 else 108 { 109 outs << ++i << "\n"; 110 outs << se2->timeString() << "\n"; 111 outs << se1->str << "\n"; 112 outs << se2->str << "\n"; 113 outs << "\n"; 114 115 ses1.removeFirst(); 116 ses2.removeFirst(); 117 } 118 } 119 120 while (!ses1.isEmpty()) 121 { 122 Session *se1 = ses1.first(); 123 124 outs << ++i << "\n"; 125 outs << se1->timeString() << "\n"; 126 outs << se1->str << "\n"; 127 outs << "\n"; 128 129 ses1.removeFirst(); 130 } 131 132 while (!ses2.isEmpty()) 133 { 134 Session *se2 = ses2.first(); 135 136 outs << ++i << "\n"; 137 outs << se2->timeString() << "\n"; 138 outs << se2->str << "\n"; 139 outs << "\n"; 140 141 ses2.removeFirst(); 142 } 143 144 out.close(); 145 edit->appendPlainText(tr("done %1").arg(s0)); 146 } 147 } 148 149 QList<Session *> MainWindow::getSessions(const QString &f) 150 { 151 QFile fp(f); 152 if (!fp.open(QIODevice::ReadOnly | QIODevice::Text)) 153 return QList<Session *>(); 154 155 QTextStream ts(&fp); 156 ts.setCodec("GBK"); 157 QString str = ts.readAll(); 158 fp.close(); 159 160 QList<Session *> list; 161 162 QRegExp re("(\\d+):(\\d+):(\\d+),(\\d+)\\s-->\\s(\\d+):(\\d+):(\\d+),(\\d+)"); 163 int p = re.indexIn(str, 0); 164 while (p != -1) 165 { 166 Session *s = new Session; 167 s->timeStart = re.cap(1).toInt() * 3600000 + re.cap(2).toInt() * 60000 + re.cap(3).toInt() * 1000 + re.cap(4).toInt(); 168 s->timeEnd = re.cap(5).toInt() * 3600000 + re.cap(6).toInt() * 60000 + re.cap(7).toInt() * 1000 + re.cap(8).toInt(); 169 170 p += re.matchedLength(); 171 int pp = p; 172 p = re.indexIn(str, p); 173 s->str = str.mid(pp, (p == -1) ? -1 : p - pp).trimmed().replace(QRegExp("(.+)\\n\\n\\d+"), "\\1").trimmed(); 174 list << s; 175 } 176 177 return list; 178 }
SubtitlesMerger_zh_CN.ts
1 <?xml version="1.0" encoding="utf-8"?> 2 <!DOCTYPE TS> 3 <TS version="2.0" language="zh_CN"> 4 <context> 5 <name>MainWindow</name> 6 <message> 7 <location filename="mainwindow.cpp" line="10"/> 8 <source>SubtitlesMerger</source> 9 <translation>字幕合并</translation> 10 </message> 11 <message> 12 <location filename="mainwindow.cpp" line="12"/> 13 <source>&Dir</source> 14 <translation>&选择目录</translation> 15 </message> 16 <message> 17 <location filename="mainwindow.cpp" line="15"/> 18 <source>&Merge</source> 19 <translation>&开始合并</translation> 20 </message> 21 <message> 22 <location filename="mainwindow.cpp" line="30"/> 23 <source>Select Directory</source> 24 <translation>选择工作目录</translation> 25 </message> 26 <message> 27 <location filename="mainwindow.cpp" line="36"/> 28 <source>setting directory to %1</source> 29 <translation>目录改变为 %1</translation> 30 </message> 31 <message> 32 <location filename="mainwindow.cpp" line="54"/> 33 <source>dir invalid</source> 34 <translation>目录不合法</translation> 35 </message> 36 <message> 37 <location filename="mainwindow.cpp" line="58"/> 38 <source>processing %1</source> 39 <translation>正在处理 %1</translation> 40 </message> 41 <message> 42 <location filename="mainwindow.cpp" line="65"/> 43 <source>output error in %1</source> 44 <translation>输出错误 %1</translation> 45 </message> 46 <message> 47 <location filename="mainwindow.cpp" line="145"/> 48 <source>done %1</source> 49 <translation>完成 %1</translation> 50 </message> 51 </context> 52 </TS>