Advertisement
DJATOM

Untitled

Feb 16th, 2019
68
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 7.04 KB | None | 0 0
  1. import sys
  2. import re
  3. from PyQt5 import QtCore, QtWidgets
  4. import tkinter as tk
  5. from tkinter import filedialog
  6. import os
  7. from collections import OrderedDict as odict
  8. from io import SEEK_CUR
  9. from struct import unpack
  10.  
  11. class MainWindow(QtWidgets.QMainWindow):
  12.     def __init__(self):
  13.         QtWidgets.QWidget.__init__(self)
  14.         self.resize(360, 100)
  15.         self.centralwidget = QtWidgets.QWidget(self)
  16.         self.centralwidget.setObjectName("centralwidget")
  17.         sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
  18.         sizePolicy.setHorizontalStretch(0)
  19.         sizePolicy.setVerticalStretch(0)
  20.         self.PrefixLabel = QtWidgets.QLabel(self.centralwidget)
  21.         self.PrefixLabel.setGeometry(QtCore.QRect(10, 10, 41, 20))
  22.         self.PrefixLabel.setObjectName("PrefixLabel")
  23.         self.PrefixLineEdit = QtWidgets.QLineEdit(self.centralwidget)
  24.         self.PrefixLineEdit.setGeometry(QtCore.QRect(50, 10, 181, 20))
  25.         self.PrefixLineEdit.setObjectName("PrefixLineEdit")
  26.         self.PrefixLineEdit.setText("EP")
  27.         self.StartFromLabel = QtWidgets.QLabel(self.centralwidget)
  28.         self.StartFromLabel.setGeometry(QtCore.QRect(250, 10, 51, 20))
  29.         self.StartFromLabel.setObjectName("StartFromLabel")
  30.         self.StartFromSpinBox = QtWidgets.QSpinBox(self.centralwidget)
  31.         self.StartFromSpinBox.setGeometry(QtCore.QRect(310, 10, 41, 20))
  32.         self.StartFromSpinBox.setObjectName("StartFromSpinBox")
  33.         self.StartFromSpinBox.setMinimum(1)
  34.         self.StartFromSpinBox.setMaximum(99)
  35.         self.OpenChaptersButton = QtWidgets.QPushButton(self.centralwidget)
  36.         self.OpenChaptersButton.setGeometry(QtCore.QRect(40, 50, 200, 23))
  37.         self.OpenChaptersButton.setObjectName("OpenChaptersButton")
  38.         self.CloseButton = QtWidgets.QPushButton(self.centralwidget)
  39.         self.CloseButton.setGeometry(QtCore.QRect(245, 50, 75, 23))
  40.         self.CloseButton.setObjectName("CloseButton")
  41.         self.setCentralWidget(self.centralwidget)
  42.         self.menubar = QtWidgets.QMenuBar(self)
  43.         self.menubar.setGeometry(QtCore.QRect(0, 0, 361, 20))
  44.         self.menubar.setObjectName("menubar")
  45.         self.setMenuBar(self.menubar)
  46.         self.statusbar = QtWidgets.QStatusBar(self)
  47.         self.statusbar.setObjectName("statusbar")
  48.         self.setStatusBar(self.statusbar)
  49.         self.CloseButton.clicked.connect(self.CloseApp)
  50.         self.OpenChaptersButton.clicked.connect(self.OpenChapters)
  51.         self.retranslateUi(self)
  52.         self.setFixedSize(self.size())
  53.  
  54.     def retranslateUi(self, MainWindow):
  55.         self.setWindowTitle("Chapter Trimmer")
  56.         self.CloseButton.setText("Close")
  57.         self.PrefixLabel.setText("Prefix:")
  58.         self.StartFromLabel.setText("Start from:")
  59.         self.OpenChaptersButton.setText("Open and Write chapters")
  60.  
  61.     def OpenChapters(self):
  62.         root = tk.Tk() # workaround
  63.         root.withdraw() # workaround
  64.         file_path = filedialog.askopenfilename(filetypes = (("Blu-ray playlists", "*.mpls"), ("All files", "*.*")))
  65.         directory = filedialog.askdirectory()
  66.         if len(file_path) > 0 and len(directory) > 0:
  67.             mplsfile = open(file_path, 'rb')
  68.             chapterdata = load(mplsfile)
  69.             mplsfile.close()
  70.             filesnum = len(chapterdata)
  71.             filePrefix = self.PrefixLineEdit.text()
  72.             fileNumber = int(self.StartFromSpinBox.text())
  73.             for file in chapterdata:
  74.                 times = file['times']
  75.                 timeDict = {}
  76.                 titleDict = {}
  77.                 namecount = 1
  78.                 chaptersList = []
  79.                 index = 0
  80.                 if len(times) > 0:
  81.                     startpos = 0
  82.                     for time in times:
  83.                         if startpos is 0:
  84.                             startpos = time
  85.                         nameFin = ''
  86.                         timeFin = self.MsecToTimeString2(float((time - startpos) / 45000.))
  87.                         namecount += 1
  88.                         last = index is len(times) - 1
  89.                         chaptersList.append('CHAPTER{index:02d}={time}\nCHAPTER{index:02d}NAME={name}'.format(index=index, time=timeFin, name=nameFin))
  90.                         if last:
  91.                             f = open('{dir}/{prefix}{number:02d}.txt'.format(dir=directory, prefix=filePrefix, number=fileNumber), 'w')
  92.                             chaptersList.pop()
  93.                             f.write('\n'.join(chaptersList))
  94.                             f.close()
  95.                             fileNumber += 1
  96.                             index = 0
  97.                             chaptersList.clear()
  98.                         index += 1
  99.  
  100.     def TimeStringToMsec(self, string):
  101.         matches = re.findall(r'(\d+):(\d+):(\d+)\.(\d+)', string, re.I)
  102.         hours, mins, secs, msecs = matches[0]
  103.         time = (int(msecs) + (int(secs) * 1000) + (int(mins) * 60 * 1000) + (int(hours) * 60 * 60 * 1000))
  104.         return time
  105.  
  106.     def MsecToTimeString2(self, sec):
  107.         secs = sec % 60
  108.         mins = sec // 60 % 60
  109.         hours = sec // 60 // 60 % 24
  110.         time = r'{:02d}:{:02d}:{:06.03f}'.format(int(hours), int(mins), secs)
  111.         return time
  112.  
  113.     def MsecToTimeString(self, msec):
  114.         msecs = msec % 1000
  115.         secs = msec // 1000 % 60
  116.         mins = msec // 1000 // 60 % 60
  117.         hours = msec // 1000 // 60 // 60 % 24
  118.         time = r'{:02d}:{:02d}:{:02d}.{:03d}'.format(hours, mins, secs, msecs)
  119.         return time
  120.  
  121.     def CloseApp(self):
  122.         sys.exit(self)
  123.  
  124. def load(f, fix_overlap=True):
  125.     def int_be(data):
  126.         return {
  127.             1: ord,
  128.             2: lambda b: unpack('>H', b)[0],
  129.             4: lambda b: unpack('>I', b)[0]
  130.         }[len(data)](data)
  131.     f.seek(8)
  132.     addr_items, addr_marks = int_be(f.read(4)), int_be(f.read(4))
  133.     f.seek(addr_items + 6)
  134.     item_count = int_be(f.read(2))
  135.     f.seek(2, SEEK_CUR)
  136.     def read_item():
  137.         block_size = int_be(f.read(2))
  138.         item = odict()
  139.         item['name'] = f.read(5).decode()
  140.         f.seek(7, SEEK_CUR)
  141.         item['times'] = [int_be(f.read(4)), int_be(f.read(4))]
  142.         f.seek(block_size-20, SEEK_CUR)
  143.         return item
  144.     items = [read_item() for _ in range(item_count)]
  145.     f.seek(addr_marks + 4)
  146.     mark_count = int_be(f.read(2))
  147.     def read_mark():
  148.         f.seek(2, SEEK_CUR)
  149.         index = int_be(f.read(2))
  150.         time = int_be(f.read(4))
  151.         f.seek(6, SEEK_CUR)
  152.         return index, time
  153.     for _ in range(mark_count):
  154.         index, time = read_mark()
  155.         if time > items[index]['times'][-2]:
  156.             items[index]['times'].insert(-1, time)
  157.     if fix_overlap:
  158.         b = None
  159.         for item in items:
  160.             a, b = b, item['times']
  161.         if a and b[0] < a[-1] < b[-1]:
  162.             a[-1] = b[0]
  163.         if len(b) > 1 and b[-1] - b[-2] < 90090:
  164.             b.pop()
  165.     return items
  166.  
  167. if __name__ == "__main__":
  168.     app = QtWidgets.QApplication(sys.argv)
  169.     w = MainWindow()
  170.     w.show()
  171.     sys.exit(app.exec_())
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement