diff --git a/Pipfile b/Pipfile index c0930e7..730cab6 100644 --- a/Pipfile +++ b/Pipfile @@ -9,6 +9,10 @@ appdirs = ">=1.4.3" lxml = ">=3.8.0" titlecase = ">=0.11.0" pygame = "*" +numpy = ">=1.21,<1.25" +opencv_python = "*" +pysubs2 = "*" +PyAudio = "*" #pyvidplayer2 = {editable = true,git = "https://github.com/ree1261/pyvidplayer2.git"} [dev-packages] diff --git a/Pipfile.lock b/Pipfile.lock index 4347176..cead062 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "312e9824c037c11e65b606532a2a8e3b0ea7e3eadcae2249c2f6336e001caec9" + "sha256": "8f503bcf50b5c267531bbd93dd8eaecf3f2cb64b900b0b34d8b0b0e3bf6669a3" }, "pipfile-spec": 6, "requires": { @@ -133,6 +133,70 @@ "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", "version": "==4.9.3" }, + "numpy": { + "hashes": [ + "sha256:04640dab83f7c6c85abf9cd729c5b65f1ebd0ccf9de90b270cd61935eef0197f", + "sha256:1452241c290f3e2a312c137a9999cdbf63f78864d63c79039bda65ee86943f61", + "sha256:222e40d0e2548690405b0b3c7b21d1169117391c2e82c378467ef9ab4c8f0da7", + "sha256:2541312fbf09977f3b3ad449c4e5f4bb55d0dbf79226d7724211acc905049400", + "sha256:31f13e25b4e304632a4619d0e0777662c2ffea99fcae2029556b17d8ff958aef", + "sha256:4602244f345453db537be5314d3983dbf5834a9701b7723ec28923e2889e0bb2", + "sha256:4979217d7de511a8d57f4b4b5b2b965f707768440c17cb70fbf254c4b225238d", + "sha256:4c21decb6ea94057331e111a5bed9a79d335658c27ce2adb580fb4d54f2ad9bc", + "sha256:6620c0acd41dbcb368610bb2f4d83145674040025e5536954782467100aa8835", + "sha256:692f2e0f55794943c5bfff12b3f56f99af76f902fc47487bdfe97856de51a706", + "sha256:7215847ce88a85ce39baf9e89070cb860c98fdddacbaa6c0da3ffb31b3350bd5", + "sha256:79fc682a374c4a8ed08b331bef9c5f582585d1048fa6d80bc6c35bc384eee9b4", + "sha256:7ffe43c74893dbf38c2b0a1f5428760a1a9c98285553c89e12d70a96a7f3a4d6", + "sha256:80f5e3a4e498641401868df4208b74581206afbee7cf7b8329daae82676d9463", + "sha256:95f7ac6540e95bc440ad77f56e520da5bf877f87dca58bd095288dce8940532a", + "sha256:9667575fb6d13c95f1b36aca12c5ee3356bf001b714fc354eb5465ce1609e62f", + "sha256:a5425b114831d1e77e4b5d812b69d11d962e104095a5b9c3b641a218abcc050e", + "sha256:b4bea75e47d9586d31e892a7401f76e909712a0fd510f58f5337bea9572c571e", + "sha256:b7b1fc9864d7d39e28f41d089bfd6353cb5f27ecd9905348c24187a768c79694", + "sha256:befe2bf740fd8373cf56149a5c23a0f601e82869598d41f8e188a0e9869926f8", + "sha256:c0bfb52d2169d58c1cdb8cc1f16989101639b34c7d3ce60ed70b19c63eba0b64", + "sha256:d11efb4dbecbdf22508d55e48d9c8384db795e1b7b51ea735289ff96613ff74d", + "sha256:dd80e219fd4c71fc3699fc1dadac5dcf4fd882bfc6f7ec53d30fa197b8ee22dc", + "sha256:e2926dac25b313635e4d6cf4dc4e51c8c0ebfed60b801c799ffc4c32bf3d1254", + "sha256:e98f220aa76ca2a977fe435f5b04d7b3470c0a2e6312907b37ba6068f26787f2", + "sha256:ed094d4f0c177b1b8e7aa9cba7d6ceed51c0e569a5318ac0ca9a090680a6a1b1", + "sha256:f136bab9c2cfd8da131132c2cf6cc27331dd6fae65f95f69dcd4ae3c3639c810", + "sha256:f3a86ed21e4f87050382c7bc96571755193c4c1392490744ac73d660e8f564a9" + ], + "index": "pypi", + "markers": "python_version >= '3.8'", + "version": "==1.24.4" + }, + "opencv-python": { + "hashes": [ + "sha256:91d5f6f5209dc2635d496f6b8ca6573ecdad051a09e6b5de4c399b8e673c60da", + "sha256:9814beca408d3a0eca1bae7e3e5be68b07c17ecceb392b94170881216e09b319", + "sha256:a7aac3900fbacf55b551e7b53626c3dad4c71ce85643645c43e91fcb19045e47", + "sha256:b983197f97cfa6fcb74e1da1802c7497a6f94ed561aba6980f1f33123f904956", + "sha256:bc31f47e05447da8b3089faa0a07ffe80e114c91ce0b171e6424f9badbd1c5cd", + "sha256:c4c406bdb41eb21ea51b4e90dfbc989c002786c3f601c236a99c59a54670a394", + "sha256:cc7adbbcd1112877a39274106cb2752e04984bc01a031162952e97450d6117f6" + ], + "markers": "python_version >= '3.6'", + "version": "==4.8.1.78" + }, + "pyaudio": { + "hashes": [ + "sha256:009f357ee5aa6bc8eb19d69921cd30e98c42cddd34210615d592a71d09c4bd57", + "sha256:126065b5e82a1c03ba16e7c0404d8f54e17368836e7d2d92427358ad44fefe61", + "sha256:12f2f1ba04e06ff95d80700a78967897a489c05e093e3bffa05a84ed9c0a7fa3", + "sha256:2a166fc88d435a2779810dd2678354adc33499e9d4d7f937f28b20cc55893e83", + "sha256:2dac0d6d675fe7e181ba88f2de88d321059b69abd52e3f4934a8878e03a7a074", + "sha256:506b32a595f8693811682ab4b127602d404df7dfc453b499c91a80d0f7bad289", + "sha256:5fce4bcdd2e0e8c063d835dbe2860dac46437506af509353c7f8114d4bacbd5b", + "sha256:78dfff3879b4994d1f4fc6485646a57755c6ee3c19647a491f790a0895bd2f87", + "sha256:858caf35b05c26d8fc62f1efa2e8f53d5fa1a01164842bd622f70ddc41f55000", + "sha256:bbeb01d36a2f472ae5ee5e1451cacc42112986abe622f735bb870a5db77cf903", + "sha256:f745109634a7c19fa4d6b8b7d6967c3123d988c9ade0cd35d4295ee1acdb53e9" + ], + "version": "==0.2.14" + }, "pygame": { "hashes": [ "sha256:03879ec299c9f4ba23901b2649a96b2143f0a5d787f0b6c39469989e2320caf1", @@ -197,12 +261,21 @@ "markers": "python_version >= '3.6'", "version": "==2.5.2" }, + "pysubs2": { + "hashes": [ + "sha256:0261611e71735ff7763972c519c72593c8063efcb9039c54af65f31b81cec116", + "sha256:1f96d9dfb5f859a54a00e04621beb20ff21ea1d788821b2f4935c5c0ef8dc68e" + ], + "index": "pypi", + "markers": "python_version >= '3.7'", + "version": "==1.6.1" + }, "six": { "hashes": [ "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==1.16.0" }, "titlecase": { diff --git a/__pycache__/app.cpython-311.pyc b/__pycache__/app.cpython-311.pyc new file mode 100644 index 0000000..01b2bfb Binary files /dev/null and b/__pycache__/app.cpython-311.pyc differ diff --git a/__pycache__/config.cpython-311.pyc b/__pycache__/config.cpython-311.pyc new file mode 100644 index 0000000..4a66bee Binary files /dev/null and b/__pycache__/config.cpython-311.pyc differ diff --git a/__pycache__/gui.cpython-311.pyc b/__pycache__/gui.cpython-311.pyc new file mode 100644 index 0000000..545ed01 Binary files /dev/null and b/__pycache__/gui.cpython-311.pyc differ diff --git a/__pycache__/mame.cpython-311.pyc b/__pycache__/mame.cpython-311.pyc new file mode 100644 index 0000000..206cb8f Binary files /dev/null and b/__pycache__/mame.cpython-311.pyc differ diff --git a/__pycache__/utils.cpython-311.pyc b/__pycache__/utils.cpython-311.pyc new file mode 100644 index 0000000..27d69b5 Binary files /dev/null and b/__pycache__/utils.cpython-311.pyc differ diff --git a/app.py b/app.py index c1c37ca..6e7eb22 100644 --- a/app.py +++ b/app.py @@ -1,31 +1,51 @@ +import sys + import pygame -from config import cfg +from pyvidplayer2 import Video -from emu import emu from gui import gui +import mame +from config import cfg, get_emu + +# BLACK = (0, 0, 0) +# WHITE = (255, 255, 255) +# GREY = (70, 70, 70) +# DARKGREY = (50, 50, 50) -class application: +class app(object): def __init__(self): - print(cfg["Engine"]) - self.gfx = gfx_pygame.gfx_pygame() + if get_emu("EmulatorType") == "MAME": + self.roms = mame.MameROMs(cfg["datadir"], cfg["HideMature"], get_emu()) + if get_emu("EmulatorType") == "MESS": + self.roms = mess.MessROMs(cfg["datadir"], get_emu()) + if get_emu("EmulatorType") == "CSV": + self.roms = csvfile.csvROMs(cfg["datadir"], get_emu()) - self.gfx.setIcon("arcade.png") + self.update_menus() + + pygame.init() + pygame.font.init() + + iconsurface = pygame.image.load("arcade.png") + pygame.display.set_icon(iconsurface) if cfg["FullScreen"]: - self.screen = self.gfx.dispSetMode(cfg["ResolutionX"], cfg["ResolutionY"], True) + self.screen = pygame.display.set_mode((cfg["ResolutionX"], cfg["ResolutionY"]), pygame.FULLSCREEN) else: - self.screen = self.gfx.dispSetMode(cfg["ResolutionX"], cfg["ResolutionY"], False) + self.screen = pygame.display.set_mode((cfg["ResolutionX"], cfg["ResolutionY"])) - self.font = self.gfx.getFont(cfg["Font"], cfg["FontSize"]) + self.font = pygame.font.Font(pygame.font.match_font(cfg["Font"]), cfg["FontSize"]) - self.status = self.gfx.getSurface(cfg["ResolutionX"], cfg["FontSize"]) + self.status_surface = pygame.Surface((cfg["ResolutionX"], self.font.get_height())) # pylint: disable=E1121 + + self.oldmouse = pygame.mouse.set_visible(False) + + pygame.key.set_repeat(100, 30) self.listwidth = int(cfg["ResolutionX"] / 2) - self.emu = emu() - - self.gui = gui(self.gfx, self.screen, self.font) + self.gui = guimodule.gui(self.screen) self.gui.add_menu( 0, @@ -33,21 +53,267 @@ class application: self.listwidth, cfg["ResolutionY"] - self.font.get_height(), border=False, - # data=self.roms, - data=["1", "2"], + data=self.roms, fg=(255, 255, 255), bg=(0, 0, 0), name="MainList", - # startitem=get_emu('CurrentGame'), - # itemattop=get_emu('GameAtTop')) - startitem=0, - itemattop=0, + startitem=get_emu("CurrentGame"), + itemattop=get_emu("GameAtTop"), ) self.gui.render() + def update_menus(self): + rootmenu = [ + "Show Artwork", + "Categories", + "Sort", + "Hide Clones" if get_emu("ShowClones") else "Show Clones", + "Change Emulator", + "Quit", + ] + sortmenu = ["Name Asc", "Name Dec", "Year Asc", "Year Dec"] + emulatormenu = get_emulators() + self.menus = { + "rootmenu": rootmenu, + "sortmenu": sortmenu, + "emulatormenu": emulatormenu, + "categorymenu": self.roms.categories, + } + def run(self): - pass + keyup = False + quitcount = 0 + while True: + event = self.gui.waitevent() + if event: + if event.type == pygame.QUIT: + break + if event.type == pygame.KEYDOWN: + keyup = False + if event.key == pygame.K_ESCAPE and self.gui.currentobject == 1: # Main List + quitcount += 1 + if quitcount == cfg["QuitKeyPresses"]: + break + elif event.key == pygame.K_ESCAPE: + quitcount = 0 + if self.gui.currentobject > 1: + self.gui.deletelastobject() + else: + quitcount = 0 + if event.key in cfg["KeySelect"] and self.gui.currentobject == 1: + if sys.platform == "darwin": + print("Running %s" % self.roms[self.gui.getcurrentitem()].name) + run_emulator(get_emu("EmulatorType"), get_emu("EXE"), self.roms[self.gui.getcurrentitem()].name) + elif event.key in cfg["KeyGameHistory"] and self.gui.currentobject == 1: + history = self.roms.get_history(self.roms[self.gui.getcurrentitem()]) + if history: + self.gui.add_notepad( + -1, -1, 800, 600, history, True, WHITE, DARKGREY, "history", "Game History" + ) + elif event.key in cfg["KeyGameInfo"] and self.gui.currentobject == 1: + info = self.roms.get_info(self.roms[self.gui.getcurrentitem()]) + if info: + self.gui.add_notepad( + -1, -1, 800, 600, info, True, WHITE, DARKGREY, "info", "Game Information" + ) + elif event.key in cfg["KeyPopup"] and self.gui.currentobject == 1: + self.gui.add_menu(40, 40, -1, -1, self.menus["rootmenu"], True, WHITE, GREY, "rootmenu", 0) + elif event.key in cfg["KeyPopup"] and self.gui.currentobject > 1: + self.gui.deletelastobject() + elif event.key in cfg["KeyShowArtwork"]: + pass + # TODO: copy from below + elif event.key in cfg["KeySelect"]: + currentitem = self.gui.getcurrentitem() + menuname = self.gui.getmenuname() + item = self.menus[menuname][currentitem] + if menuname == "rootmenu": + if item == "Quit": + break + elif item == "Show Artwork": + print("hello") + aw = self.roms.get_artwork(self.roms[self.gui.getcurrentitem(0)]) + if aw != []: + self.gui.add_image_notepad( + -1, -1, 800, 600, aw, True, WHITE, DARKGREY, "artwork", "Artwork" + ) + elif item == "Categories": + self.gui.add_menu( + 80, + 45, + -1, + -(self.screen.get_height() - 45 - (self.font.get_height() * 2) - 8), + self.menus["categorymenu"], + True, + WHITE, + GREY, + "categorymenu", + 0, + ) + elif item == "Sort": + self.gui.add_menu( + 80, 45, -1, -1, self.menus["sortmenu"], True, WHITE, GREY, "sortmenu", 0 + ) + elif item == "Show Clones": + set_emu("ShowClones", True) + self.update_menus() + self.roms.filter() + self.gui.deleteallmenus() + self.gui.setcurrentitem(0) + elif item == "Hide Clones": + set_emu("ShowClones", False) + self.update_menus() + self.roms.filter() + self.gui.deleteallmenus() + self.gui.setcurrentitem(0) + elif item == "Change Emulator": + self.gui.add_menu( + 80, + 45, + -1, + -(self.screen.get_height() - 45 - (self.font.get_height() * 2) - 8), + self.menus["emulatormenu"], + True, + WHITE, + GREY, + "emulatormenu", + 0, + ) + elif menuname == "sortmenu": + set_emu("Sort", item) + self.roms.filter() + self.gui.deleteallmenus() + elif menuname == "categorymenu": + set_emu("Category", item) + self.roms.filter() + self.gui.deleteallmenus() + self.gui.setcurrentitem(0) + elif menuname == "emulatormenu": + cfg["Emulator"] = item + if get_emu("EmulatorType") == "MAME": + self.roms = mame.MameROMs(cfg["datadir"], cfg["HideMature"], get_emu()) + if get_emu("EmulatorType") == "MESS": + self.roms = mess.MessROMs(cfg["datadir"], get_emu()) + if get_emu("EmulatorType") == "CSV": + self.roms = csvfile.csvROMs(cfg["datadir"], get_emu()) + + self.update_menus() + self.gui.deleteallmenus() + self.gui.deletelastobject() + self.gui.add_menu( + 0, + 0, + self.listwidth, + cfg["ResolutionY"] - self.font.get_height(), + border=False, + data=self.roms, + fg=(255, 255, 255), + bg=(0, 0, 0), + name="MainList", + startitem=get_emu("CurrentGame"), + itemattop=get_emu("GameAtTop"), + ) + + if event.type == pygame.KEYUP: + keyup = True + + if self.gui.currentobject == 1 and self.roms: + currentitem = self.gui.getcurrentitem() + + self.screen.fill(BLACK) + self.status_surface.fill((128, 128, 128)) + + if keyup: + pass + if cfg["AlwaysChangeSnap"] or keyup: + data = self.roms.get_snap(self.roms[currentitem], "snap") + screenshot_surface = image_from_data(data, (508, 480)) + + if cfg["ScanLines"]: + screenshot_surface = addscanlines(screenshot_surface) + + self.screen.blit( + screenshot_surface, + ( + self.listwidth + + 2 + + ((self.screen.get_width() - self.listwidth + 2) / 2) + - (screenshot_surface.get_width() / 2), + 102, + ), + ) + + data = self.roms.get_snap(self.roms[currentitem], "marquee") + marquee_surface = image_from_data(data, (640, 100)) + + self.screen.blit( + marquee_surface, + ( + self.listwidth + + 2 + + ((self.screen.get_width() - self.listwidth + 2) / 2) + - (marquee_surface.get_width() / 2), + 0, + ), + ) + + data = self.roms.get_snap(self.roms[currentitem], "title") + title_surface = image_from_data( + data, + ( + 640, + cfg["ResolutionY"] + - ( + screenshot_surface.get_height() + + marquee_surface.get_height() + + 4 + + self.status_surface.get_height() + ), + ), + ) + + self.screen.blit( + title_surface, + ( + self.listwidth + + 2 + + ((self.screen.get_width() - self.listwidth + 2) / 2) + - (title_surface.get_width() / 2), + (screenshot_surface.get_height() + marquee_surface.get_height() + 4), + ), + ) + + size = self.font.size("%d / %d %s" % (currentitem + 1, len(self.roms), get_emu("Sort")))[0] + + self.status_surface.blit( + self.font.render( + "%d / %d %s" % (currentitem + 1, len(self.roms), get_emu("Sort")), True, BLACK, (128, 128, 128) + ), + (cfg["ResolutionX"] - size - 5, 0), + ) + self.status_surface.blit( + self.font.render( + "%s %s" % (self.roms[currentitem].year, self.roms[currentitem].category), + True, + BLACK, + (128, 128, 128), + ), + (5, 0), + ) + + try: + self.screen.blit(self.status_surface, (0, cfg["ResolutionY"] - self.font.get_height())) + except: + pass + self.gui.render() - self.gfx.tick(60) + + pygame.mouse.set_visible(self.oldmouse) + pygame.key.set_repeat() + + set_emu("CurrentGame", self.gui.getcurrentitem()) + set_emu("GameAtTop", self.gui.getitemattop()) + + config_write() diff --git a/config.py b/config.py index 9ba88b7..994ecc0 100644 --- a/config.py +++ b/config.py @@ -137,15 +137,16 @@ def config_write(): cfg[item] = t[item] -# def get_emu(option=None): -# if option: -# r = cfg[cfg['Emulator']][option] -# else: -# r = cfg[cfg['Emulator']] -# return r +def get_emu(option=None): + if option: + r = cfg[cfg["Emulator"]][option] + else: + r = cfg[cfg["Emulator"]] + return r -# def set_emu(option, data): -# cfg[cfg['Emulator']][option] = data + +def set_emu(option, data): + cfg[cfg["Emulator"]][option] = data def get_emulators(): diff --git a/gui.py b/gui.py index 704034e..c42b798 100644 --- a/gui.py +++ b/gui.py @@ -3,7 +3,7 @@ import pygame from pygame.locals import KEYDOWN from config import cfg -from utils import wrap_multi_line, image_from_data +from utils import wrap_multi_line # pylint: disable=E1121,R0902,R0903,R0912,R0913 diff --git a/pyvidplayer2/.gitignore b/pyvidplayer2/.gitignore deleted file mode 100644 index 2f57176..0000000 --- a/pyvidplayer2/.gitignore +++ /dev/null @@ -1,10 +0,0 @@ -__pycache__/ -build/ -dist/ -*.egg-info/ -build.txt -test.py -test.mp4 -resources/ -.VSCodeCounter/ -video/ \ No newline at end of file diff --git a/pyvidplayer2/LICENSE b/pyvidplayer2/LICENSE deleted file mode 100644 index 2490cba..0000000 --- a/pyvidplayer2/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2023 ree1261 - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/pyvidplayer2/README.md b/pyvidplayer2/README.md deleted file mode 100644 index 55a365e..0000000 --- a/pyvidplayer2/README.md +++ /dev/null @@ -1,85 +0,0 @@ -# pyvidplayer2 (please report all bugs!) - -Introducing pyvidplayer2, the successor to pyvidplayer. It's better in -pretty much every way, and finally allows an easy and reliable way to play videos in Python. - -All the features from the original library have been ported over, with the exception of ```alt_resize()```. Since pyvidplayer2 has a completely revamped foundation, the unreliability of ```set_size()``` has been quashed, and a fallback function is now redundant. - -# Features (tested on Windows) -- Easy to implement (4 lines of code) -- Fast and reliable -- Adjust playback speed -- No audio/video sync issues -- Subtitle support (.srt, .ass, etc) -- Play multiple videos in parallel -- Built in GUI -- Support for Pygame, Pyglet, Tkinter, and PyQT6 -- Can play all ffmpeg supported video formats -- Post process effects -- Webcam feed - -# Installation -``` -pip install pyvidplayer2 -``` -Note: FFMPEG (just the essentials is fine) must be installed and accessible via the system PATH. Here's an online article on how to do this (windows): -https://phoenixnap.com/kb/ffmpeg-windows. - -# Quickstart - -Refer to the examples folder for more basic guides, and documentation.md contains more detailed information. - -``` -import pygame -from pyvidplayer2 import Video - - -# create video object - -vid = Video("video.mp4") - -win = pygame.display.set_mode(vid.current_size) -pygame.display.set_caption(vid.name) - - -while vid.active: - key = None - for event in pygame.event.get(): - if event.type == pygame.QUIT: - vid.stop() - elif event.type == pygame.KEYDOWN: - key = pygame.key.name(event.key) - - if key == "r": - vid.restart() #rewind video to beginning - elif key == "p": - vid.toggle_pause() #pause/plays video - elif key == "m": - vid.toggle_mute() #mutes/unmutes video - elif key == "right": - vid.seek(15) #skip 15 seconds in video - elif key == "left": - vid.seek(-15) #rewind 15 seconds in video - elif key == "up": - vid.set_volume(1.0) #max volume - elif key == "down": - vid.set_volume(0.0) #min volume - elif key == "1": - vid.set_speed(1.0) #regular playback speed - elif key == "2": - vid.set_speed(2.0) #doubles video speed - - # only draw new frames, and only update the screen if something is drawn - - if vid.draw(win, (0, 0), force_draw=False): - pygame.display.update() - - pygame.time.wait(16) # around 60 fps - - -# close video when done - -vid.close() -pygame.quit() - -``` \ No newline at end of file diff --git a/pyvidplayer2/pyvidplayer2/__init__.py b/pyvidplayer2/__init__.py similarity index 100% rename from pyvidplayer2/pyvidplayer2/__init__.py rename to pyvidplayer2/__init__.py diff --git a/pyvidplayer2/__pycache__/__init__.cpython-311.pyc b/pyvidplayer2/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000..d5dbb6b Binary files /dev/null and b/pyvidplayer2/__pycache__/__init__.cpython-311.pyc differ diff --git a/pyvidplayer2/__pycache__/error.cpython-311.pyc b/pyvidplayer2/__pycache__/error.cpython-311.pyc new file mode 100644 index 0000000..e838935 Binary files /dev/null and b/pyvidplayer2/__pycache__/error.cpython-311.pyc differ diff --git a/pyvidplayer2/__pycache__/mixer_handler.cpython-311.pyc b/pyvidplayer2/__pycache__/mixer_handler.cpython-311.pyc new file mode 100644 index 0000000..09d9d39 Binary files /dev/null and b/pyvidplayer2/__pycache__/mixer_handler.cpython-311.pyc differ diff --git a/pyvidplayer2/__pycache__/post_processing.cpython-311.pyc b/pyvidplayer2/__pycache__/post_processing.cpython-311.pyc new file mode 100644 index 0000000..a86d2ad Binary files /dev/null and b/pyvidplayer2/__pycache__/post_processing.cpython-311.pyc differ diff --git a/pyvidplayer2/__pycache__/pyaudio_handler.cpython-311.pyc b/pyvidplayer2/__pycache__/pyaudio_handler.cpython-311.pyc new file mode 100644 index 0000000..e71be82 Binary files /dev/null and b/pyvidplayer2/__pycache__/pyaudio_handler.cpython-311.pyc differ diff --git a/pyvidplayer2/__pycache__/subtitles.cpython-311.pyc b/pyvidplayer2/__pycache__/subtitles.cpython-311.pyc new file mode 100644 index 0000000..8cb04e0 Binary files /dev/null and b/pyvidplayer2/__pycache__/subtitles.cpython-311.pyc differ diff --git a/pyvidplayer2/__pycache__/video.cpython-311.pyc b/pyvidplayer2/__pycache__/video.cpython-311.pyc new file mode 100644 index 0000000..e455fa5 Binary files /dev/null and b/pyvidplayer2/__pycache__/video.cpython-311.pyc differ diff --git a/pyvidplayer2/__pycache__/video_player.cpython-311.pyc b/pyvidplayer2/__pycache__/video_player.cpython-311.pyc new file mode 100644 index 0000000..72a9303 Binary files /dev/null and b/pyvidplayer2/__pycache__/video_player.cpython-311.pyc differ diff --git a/pyvidplayer2/__pycache__/video_pygame.cpython-311.pyc b/pyvidplayer2/__pycache__/video_pygame.cpython-311.pyc new file mode 100644 index 0000000..e1b8e2b Binary files /dev/null and b/pyvidplayer2/__pycache__/video_pygame.cpython-311.pyc differ diff --git a/pyvidplayer2/__pycache__/video_tkinter.cpython-311.pyc b/pyvidplayer2/__pycache__/video_tkinter.cpython-311.pyc new file mode 100644 index 0000000..f62060d Binary files /dev/null and b/pyvidplayer2/__pycache__/video_tkinter.cpython-311.pyc differ diff --git a/pyvidplayer2/__pycache__/webcam.cpython-311.pyc b/pyvidplayer2/__pycache__/webcam.cpython-311.pyc new file mode 100644 index 0000000..a83cca0 Binary files /dev/null and b/pyvidplayer2/__pycache__/webcam.cpython-311.pyc differ diff --git a/pyvidplayer2/documentation.md b/pyvidplayer2/documentation.md deleted file mode 100644 index 772a63c..0000000 --- a/pyvidplayer2/documentation.md +++ /dev/null @@ -1,180 +0,0 @@ -# Video(path, chunk_size=300, max_threads=1, max_chunks=1, subs=None, post_process=PostProcessing.none, interp=cv2.INTER_LINEAR, use_pygame_audio=False) - -Main object used to play videos. It uses FFMPEG to extract chunks of audio from videos and then feeds it into a Pyaudio stream. Finally, it uses OpenCV to display the appropriate video frames. Videos can only be played simultaneously if they're using Pyaudio (see use_pygame_audio below). This object uses Pygame for graphics. See bottom for other supported libraries. - -## Arguments - - ```path``` - Path to video file. I tested a few popular video types, such as mkv, mp4, mov, avi, and 3gp, but theoretically anything FFMPEG can extract data from should work. - - ```chunk_size``` - How much audio is extracted at a time, in seconds. Increasing this value can mean less total extracts, but slower extracts. - - ```max_threads``` - Maximum number of chunks that can be extracted at any given time. Increasing this value can speed up extract at the expense of cpu usage. - - ```max_chunks``` - Maximum number of chunks allowed to be extracted and reserved. Increasing this value can help with buffering, but will use more memory. - - ```subs``` - Pass a Subtitle class here for the video to display subtitles. - - ```post_process``` - Post processing function that is applied whenever a frame is rendered. This is PostProcessing.none by default, which means no alterations are taking place. - - ```interp``` - Interpolation technique used when resizing frames. In general, the three main ones are cv2.INTER_LINEAR, which is balanced, cv2.INTER_CUBIC, which is slower but produces better results, and cv2.INTER_AREA, which is better for downscaling. - - ```use_pygame_audio``` - Specifies whether to use Pyaudio or Pygame to play audio. - -## Attributes - - ```path``` - Same as given argument. - - ```name``` - Name of file without the directory and extension. - - ```ext``` - Type of video (mp4, mkv, mov, etc). - - ```frame``` - Current frame index. Starts from 0. - - ```frame_rate``` - How many frames are in one second. - - ```frame_count``` - How many total frames there are. - - ```frame_delay``` - Time between frames in order to maintain frame rate (in fractions of a second). - - ```duration``` - Length of video in seconds. - - ```original_size``` - - ```current_size``` - - ```aspect_ratio``` - Width divided by height. - - ```chunk_size``` - Same as given argument. - - ```max_chunks``` - Same as given argument. - - ```max_threads``` - Same as given argument. - - ```frame_data``` - Current video frame as a NumPy ndarray. - - ```frame_surf``` - Current video frame as a Pygame Surface. - - ```active``` - Whether the video is currently playing. This is unaffected by pausing and resuming. - - ```buffering``` - Whether the video is waiting for audio to extract. - - ```paused``` - - ```muted``` - - ```speed``` - Float from 0.5 to 10.0 that multiplies the playback speed. - - ```subs``` - Same as given argument. - - ```post_func``` - Same as given argument. - - ```interp``` - Same as given argument. - - ```use_pygame_audio``` - Same as given argument. - -## Methods - - ```play()``` - - ```stop()``` - - ```resize(size)``` - - ```change_resolution(height)``` - Given a height, the video will scale its width while maintaining aspect ratio. - - ```close()``` - Releases resources. Always recommended to call when done. - - ```restart() ``` - - ```set_speed(speed)``` - Accepts a float from 0.5 (half speed) to 10.0 (ten times speed) - - ```get_speed()``` - - ```set_volume(volume)``` - Adjusts the volume of the video, from 0.0 (min) to 1.0 (max). - - ```get_volume()``` - - ```get_paused()``` - - ```toggle_pause()``` - Pauses if the video is playing, and resumes if the video is paused. - - ```pause()``` - - ```resume()``` - - ```toggle_mute()``` - - ```mute()``` - - ```unmute()``` - - ```get_pos()``` - Returns the current position in seconds. - - ```seek(time, relative=True)``` - Changes the current position in the video. If relative is true, the given time will be added or subtracted to the current time. Otherwise, the current position will be set to the given time exactly. Time must be given in seconds, and seeking will be accurate to one tenth of a second. - - ```draw(surf, pos, force_draw=True)``` - Draws the current video frame onto the given surface, at the given position. If force_draw is true, a surface will be drawn every time this is called. Otherwise, only new frames will be drawn. This reduces cpu usage, but will cause flickering if anything is drawn under or above the video. This method also returns whether a frame was drawn. - - ```preview()``` - Opens a window and plays the video. This method will hang until the video closes. Videos are played at 60 fps with force_draw disabled. - -# VideoPlayer(video, rect, interactable=True, loop=False, preview_thumbnails=0) - -VideoPlayers are GUI containers for videos. This seeks to mimic standard video players, so clicking it will play/pause playback, and the GUI will only show when the mouse is hovering over it. Only supported for Pygame. - -## Arguments - - ```video``` - Video object to play. - - ```rect``` - An x, y, width, and height of the VideoPlayer. The topleft corner will be the x, y coordinate. - - ```interactable``` - Enables the GUI. - - ```loop``` - Whether the contained video will restart after it finishes. If the queue is not empty, the entire queue will loop, not just the current video. - - ```preview_thumbnails``` - Number of preview thumbnails loaded and saved in memory. When seeking, a preview window will show the closest loaded frame. The higher this number is, the more frames are loaded, increasing the preview accuracy, but also increasing initial load time and memory usage. Because of this, this value is defaulted to 0, which turns seek previewing off. - -## Attributes - - ```video``` - Same as given argument. - - ```frame_rect``` - Same as given argument. - - ```vid_rect``` - This is the video fitted into the frame_rect while maintaining aspect ratio. Black bars will appear in any unused space. - - ```interactable``` - Same as given argument. - - ```loop``` - Same as given argument. - - ```queue_``` - Videos to play after the current one finishes. - - ```preview_thumbnails``` - Same as given argument. - -## Methods - - ```zoom_to_fill()``` - Zooms in the video so that the entire frame_rect is filled in, while maintaining aspect ratio. - - ```zoom_out()``` - Reverts zoom_to_fill() - - ```queue(input)``` - Accepts a path to a video or a Video object and adds it to the queue. Passing a path will not load the video until it becomes the active video. Passing a Video object will cause it to silently load its first audio chunk, so changing videos will be as seamless as possible. - - ```get_queue()``` - - ```resize(size)``` - - ```move(pos, relative)``` - Moves the VideoPlayer. If relative is true, the given coordinates will be added onto the current coordinates. Otherwise, the current coordinates will be set to the given coordinates. - - ```update(events, show_ui=None)``` - Allows the VideoPlayer to make calculations. It must be given the returns of pygame.event.get(). The GUI automatically shows up when your mouse hovers over the video player, so show_ui can be used to override that. This method also returns show_ui. - - ```draw(surface)``` - Draws the VideoPlayer onto the given Surface. - - ```close()``` - Releases resources. Always recommended to call when done. - - ```skip()``` - Moves onto the next video in the queue. - - ```get_video()``` - Returns currently playing video. - -# Subtitles(path, colour="white", highlight=(0, 0, 0, 128), font=pygame.font.SysFont("arial", 30), encoding="utf-8-sig") - -Object used for handling subtitles. Only supported for Pygame. - -## Arguments - - ```path``` - Path to subtitle file. This can be any file pysubs2 can read, including .srt, .ass, .vtt, and others. - - ```colour``` - Colour of text. - - ```highlight``` - Background colour of text. Accepts RGBA, so it can be made completely transparent. - - ```font``` - Pygame Font or SysFont object used to render Surfaces. This includes the size of the text. - - ```encoding``` - Encoding used to open the srt file. - - ```offset``` - The higher this number is, the close the subtitle is to the top of the screen. - -## Attributes - - ```path``` - Same as given argument. - - ```encoding``` - Same as given argument. - - ```start``` - Starting timestamp of current subtitle. - - ```end``` - Ending timestamp of current subtitle. - - ```text``` - Current subtitle text. - - ```surf``` - Current text in a Pygame Surface. - - ```colour``` - Same as given argument. - - ```highlight``` - Same as given argument. - - ```font``` - Same as given argument. - - ```offset``` - Same as given argument. - -## Methods - - ```set_font(font)``` - - ```get_font()``` - -# Webcam(post_process=PostProcessing.none, interp=cv2.INTER_LINEAR, fps=30) - -Object used for displaying a webcam feed. Only supported for Pygame. - -## Arguments - - ```post_process``` - Post processing function that is applied whenever a frame is rendered. This is PostProcessing.none by default, which means no alterations are taking place. - - ```interp``` - Interpolation technique used when resizing frames. In general, the three main ones are cv2.INTER_LINEAR, which is balanced, cv2.INTER_CUBIC, which is slower but produces better results, and cv2.INTER_AREA, which is better for downscaling. - - ```fps``` - Maximum number of frames captured from the webcam per second. - -## Attributes - - ```post_process``` - Same as given argument. - - ```interp``` - Same as given argument. - - ```fps``` - Same as given argument. - - ```original_size``` - - ```current_size``` - - ```aspect_ratio``` - Width divided by height. - - ```active``` - Whether the webcam is currently playing. - - ```frame_data``` - Current video frame as a NumPy ndarray. - - ```frame_surf``` - Current video frame as a Pygame Surface. - -## Methods - - ```play()``` - - ```stop()``` - - ```resize(size)``` - - ```change_resolution(height)``` - Given a height, the video will scale its width while maintaining aspect ratio. - - ```close()``` - Releases resources. Always recommended to call when done. - - ```get_pos()``` - Returns how long the webcam has been active. Is not reset if webcam is stopped. - - ```draw(surf, pos, force_draw=True)``` - Draws the current video frame onto the given surface, at the given position. If force_draw is true, a surface will be drawn every time this is called. Otherwise, only new frames will be drawn. This reduces cpu usage, but will cause flickering if anything is drawn under or above the video. This method also returns whether a frame was drawn. - - ```preview()``` - Opens a window and plays the webcam. This method will hang until the window is closed. Videos are played at whatever fps the webcam object is set to. - -# PostProcessing -Used to apply various filters to video playback. Mostly for fun. Works across all graphics libraries. - - ```none``` - Default. Nothing happens. - - ```blur``` - Slightly blurs frames. - - ```sharpen``` - An okay-looking sharpen. Looks pretty bad for small resolutions. - - ```greyscale``` - Removes colour from frame. - - ```noise``` - Adds a static-like filter. Very intensive. - - ```letterbox``` - Adds black bars above and below the frame to look more cinematic. - - ```cel_shading``` - Thickens borders for a comic book style filter. - -# Supported Graphics Libraries - - Pygame (```Video```) <- default and best supported - - Tkinter (```VideoTkinter```) - - Pyglet (```VideoPyglet```) - - PyQT6 (```VideoPyQT```) - -To use other libraries instead of Pygame, use their respective video object. Each preview method will use their respective graphics API to create a window and draw frames. See the examples folder for details. Note that Subtitles, Webcam, and VideoPlayer only work with Pygame installed. - -# Get Version - -``` -print(pyvidplayer2.get_version_info()) -``` - -Returns a dictionary with the version of pyvidplayer2, FFMPEG, and Pygame. \ No newline at end of file diff --git a/pyvidplayer2/pyvidplayer2/error.py b/pyvidplayer2/error.py similarity index 100% rename from pyvidplayer2/pyvidplayer2/error.py rename to pyvidplayer2/error.py diff --git a/pyvidplayer2/examples/resources/billiejean.mp4 b/pyvidplayer2/examples/resources/billiejean.mp4 new file mode 100644 index 0000000..3b19e99 Binary files /dev/null and b/pyvidplayer2/examples/resources/billiejean.mp4 differ diff --git a/pyvidplayer2/examples/resources/birds.avi b/pyvidplayer2/examples/resources/birds.avi new file mode 100644 index 0000000..dcfe5a9 Binary files /dev/null and b/pyvidplayer2/examples/resources/birds.avi differ diff --git a/pyvidplayer2/examples/resources/clip.mp4 b/pyvidplayer2/examples/resources/clip.mp4 new file mode 100644 index 0000000..f896c1e Binary files /dev/null and b/pyvidplayer2/examples/resources/clip.mp4 differ diff --git a/pyvidplayer2/examples/resources/font.ttf b/pyvidplayer2/examples/resources/font.ttf new file mode 100644 index 0000000..362a7e1 Binary files /dev/null and b/pyvidplayer2/examples/resources/font.ttf differ diff --git a/pyvidplayer2/examples/resources/medic.mov b/pyvidplayer2/examples/resources/medic.mov new file mode 100644 index 0000000..9fd55d9 Binary files /dev/null and b/pyvidplayer2/examples/resources/medic.mov differ diff --git a/pyvidplayer2/examples/resources/ocean.mkv b/pyvidplayer2/examples/resources/ocean.mkv new file mode 100644 index 0000000..1601f8f Binary files /dev/null and b/pyvidplayer2/examples/resources/ocean.mkv differ diff --git a/pyvidplayer2/examples/resources/subs1.srt b/pyvidplayer2/examples/resources/subs1.srt new file mode 100644 index 0000000..efb7b84 --- /dev/null +++ b/pyvidplayer2/examples/resources/subs1.srt @@ -0,0 +1,107 @@ +1 +00:00:00,875 --> 00:00:01,710 +Oh, my God! + +2 +00:00:05,171 --> 00:00:05,880 +Hang on! + +3 +00:00:06,297 --> 00:00:08,383 +- Ethan! +- Go, go, go! + +4 +00:00:08,383 --> 00:00:11,761 +Audiences and critics can't believe +what they're seeing. + +5 +00:00:14,139 --> 00:00:15,015 +Listen to me. + +6 +00:00:15,015 --> 00:00:16,850 +The world's coming after you. + +7 +00:00:16,850 --> 00:00:18,101 +Stay out of my way. + +8 +00:00:18,935 --> 00:00:21,187 +“Tom Cruise has outdone himself.” + +9 +00:00:22,105 --> 00:00:25,025 +With a 99% on Rotten Tomatoes. + +10 +00:00:25,025 --> 00:00:25,483 +Yes! + +11 +00:00:25,483 --> 00:00:29,446 +“Mission: Impossible - Dead Reckoning is filled with ‘holy shit’ moments.” + +12 +00:00:29,446 --> 00:00:30,488 +What is happening? + +13 +00:00:30,488 --> 00:00:32,490 +“This is why we go to the movies.” + +14 +00:00:33,908 --> 00:00:35,577 +Oh, I like her. + +15 +00:00:35,577 --> 00:00:37,287 +“It's pulse pounding.” + +16 +00:00:37,746 --> 00:00:39,622 +“It will rock your world.” + +17 +00:00:40,081 --> 00:00:41,875 +With “jaw dropping action.” + +18 +00:00:43,209 --> 00:00:44,085 +Is this where we run? + +19 +00:00:44,085 --> 00:00:44,919 +Go, go, go, go! + +20 +00:00:45,253 --> 00:00:45,920 +Probably. + +21 +00:00:46,421 --> 00:00:49,132 +“It's one of the best action movies +ever made.” + +22 +00:00:49,466 --> 00:00:50,508 +What more can I say? + +23 +00:00:50,925 --> 00:00:54,888 +“See it in the biggest, most seat-shaking theater you can find.” + +24 +00:00:55,138 --> 00:00:57,891 +“It will take your breath away.” + +25 +00:00:58,808 --> 00:00:59,893 +Ethan, did you make it? + +26 +00:00:59,893 --> 00:01:00,852 +Are you okay? + diff --git a/pyvidplayer2/examples/resources/subs2.srt b/pyvidplayer2/examples/resources/subs2.srt new file mode 100644 index 0000000..e3b2c73 --- /dev/null +++ b/pyvidplayer2/examples/resources/subs2.srt @@ -0,0 +1,283 @@ +1 +00:00:02,814 --> 00:00:04,402 +♪♪ + +2 +00:00:04,453 --> 00:00:06,613 +EMBER +Meet the residents of Element City. + +3 +00:00:08,156 --> 00:00:10,507 +EMBER +Air... usually has their +head in the clouds. + +4 +00:00:11,313 --> 00:00:12,855 +AIR PERSON +Aww, my new jacket! + +5 +00:00:13,570 --> 00:00:15,594 +EMBER +Earth... can be a little seedy. + +6 +00:00:16,875 --> 00:00:18,240 +EARTH PERSON +Nothing weird going on here. + +7 +00:00:18,291 --> 00:00:20,156 +EARTH PERSON +Uh, just a little pruning! + +8 +00:00:20,810 --> 00:00:22,774 +EMBER +Water... is always getting into something. + +9 +00:00:22,825 --> 00:00:25,169 +YOUNG WADE +Oh... Huh... + +10 +00:00:25,935 --> 00:00:26,935 +YOUNG WADE +[Screams] + +11 +00:00:28,341 --> 00:00:29,094 +YOUNG WADE +Help! + +12 +00:00:29,583 --> 00:00:30,709 +EMBER +And fire... + +13 +00:00:31,302 --> 00:00:32,041 +EMBER +As ordered! + +14 +00:00:32,091 --> 00:00:33,404 +EMBER +We run a little hot. + +15 +00:00:35,717 --> 00:00:37,294 +[Burps] + +16 +00:00:37,794 --> 00:00:40,413 +BERNIE +This shop is dream of our family. + +17 +00:00:40,463 --> 00:00:42,396 +BERNIE +Someday it'll all be yours! + +18 +00:00:43,256 --> 00:00:45,626 +EMBER +But we all live by one simple rule. + +19 +00:00:46,615 --> 00:00:48,469 +CINDER +Elements cannot mix! + +20 +00:00:51,256 --> 00:00:52,095 +WADE +[Screams] + +21 +00:00:52,146 --> 00:00:52,818 +EMBER +What the... + +22 +00:00:52,868 --> 00:00:54,812 +WADE +The pipe squished me all out of shape. + +23 +00:00:54,863 --> 00:00:55,565 +EMBER +Dang! + +24 +00:00:57,287 --> 00:00:58,051 +WADE +That's better. + +25 +00:00:58,102 --> 00:00:58,896 +EMBER +Oh. + +26 +00:01:00,310 --> 00:01:02,055 +WADE +So you've never left Fire Town? + +27 +00:01:02,106 --> 00:01:03,720 +EMBER +Sorry, buddy. Elements don't mix. + +28 +00:01:04,160 --> 00:01:05,243 +EARTH PERSON +Hey! + +29 +00:01:05,340 --> 00:01:07,399 +EMBER +Plus, my dad would boil you alive. + +30 +00:01:07,449 --> 00:01:09,040 +WADE +Why does anyone get to tell you + +31 +00:01:09,090 --> 00:01:10,416 +WADE +what you can do in your life? + +32 +00:01:10,840 --> 00:01:11,453 +WADE +Come on! + +33 +00:01:15,160 --> 00:01:16,290 +WADE +Why do they even have these? + +34 +00:01:16,340 --> 00:01:17,253 +EMBER +Eh, who knows. + +35 +00:01:18,959 --> 00:01:19,973 +WADE +Watch this! + +36 +00:01:20,024 --> 00:01:22,042 +♪♪ + +37 +00:01:22,106 --> 00:01:22,704 +EMBER +Whoa! + +38 +00:01:25,531 --> 00:01:27,695 +BERNIE +Ember, I see a change in you. + +39 +00:01:27,853 --> 00:01:28,690 +WADE +[Screaming] + +40 +00:01:29,156 --> 00:01:30,601 +CINDER +Water guy? + +41 +00:01:31,125 --> 00:01:31,980 +EMBER +You live here? + +42 +00:01:32,031 --> 00:01:33,267 +WADE +It's my mom's place. + +43 +00:01:33,317 --> 00:01:34,371 +ALAN +We got two kids that are + +44 +00:01:34,421 --> 00:01:35,733 +ALAN +swimming around here somewhere. + +45 +00:01:36,187 --> 00:01:38,281 +ALAN +Marco! Polo! + +46 +00:01:38,734 --> 00:01:40,187 +MARCO +What? [Laughing] + +47 +00:01:43,140 --> 00:01:45,597 +EMBER +I've been trying to fill my father's shoes + +48 +00:01:45,648 --> 00:01:48,589 +EMBER +but I never once asked +what I wanted to do. + +49 +00:01:48,640 --> 00:01:50,671 +♪♪ + +50 +00:01:53,717 --> 00:01:54,732 +BERNIE +Try this! + +51 +00:01:54,783 --> 00:01:56,186 +EMBER +Dad, those are too hot. + +52 +00:01:56,273 --> 00:01:57,233 +WADE +I love hot food. + +53 +00:01:57,876 --> 00:01:59,047 +WADE +[Gulps] + +54 +00:02:00,570 --> 00:02:01,491 +WADE +[Screaming] + +55 +00:02:01,542 --> 00:02:02,875 +WADE +[Muffled screaming] + +56 +00:02:05,903 --> 00:02:07,520 +WADE +[Screaming] + +57 +00:02:07,879 --> 00:02:10,048 +EMBER +You see? He likes it! + diff --git a/pyvidplayer2/examples/resources/trailer1.mp4 b/pyvidplayer2/examples/resources/trailer1.mp4 new file mode 100644 index 0000000..1daed55 Binary files /dev/null and b/pyvidplayer2/examples/resources/trailer1.mp4 differ diff --git a/pyvidplayer2/examples/resources/trailer2.mp4 b/pyvidplayer2/examples/resources/trailer2.mp4 new file mode 100644 index 0000000..8d51b03 Binary files /dev/null and b/pyvidplayer2/examples/resources/trailer2.mp4 differ diff --git a/pyvidplayer2/pyvidplayer2/mixer_handler.py b/pyvidplayer2/mixer_handler.py similarity index 100% rename from pyvidplayer2/pyvidplayer2/mixer_handler.py rename to pyvidplayer2/mixer_handler.py diff --git a/pyvidplayer2/pyvidplayer2/post_processing.py b/pyvidplayer2/post_processing.py similarity index 100% rename from pyvidplayer2/pyvidplayer2/post_processing.py rename to pyvidplayer2/post_processing.py diff --git a/pyvidplayer2/pyvidplayer2/pyaudio_handler.py b/pyvidplayer2/pyaudio_handler.py similarity index 100% rename from pyvidplayer2/pyvidplayer2/pyaudio_handler.py rename to pyvidplayer2/pyaudio_handler.py diff --git a/pyvidplayer2/requirements.txt b/pyvidplayer2/requirements.txt deleted file mode 100644 index 1bdd1a4..0000000 --- a/pyvidplayer2/requirements.txt +++ /dev/null @@ -1,5 +0,0 @@ -numpy<1.25,>=1.21 -opencv_python -pygame -pysubs2 -PyAudio \ No newline at end of file diff --git a/pyvidplayer2/setup.py b/pyvidplayer2/setup.py deleted file mode 100644 index f8e824c..0000000 --- a/pyvidplayer2/setup.py +++ /dev/null @@ -1,27 +0,0 @@ -from setuptools import setup -from pyvidplayer2 import _VERSION - - -with open("README.md", 'r') as f: - long_desc = f.read() - - -setup( - name="pyvidplayer2", - version=_VERSION, - description="Video playback in Python", - long_description=long_desc, - long_description_content_type = "text/markdown", - author="Anray Liu", - author_email="anrayliu@gmail.com", - license="MIT", - packages=["pyvidplayer2"], - install_requires=["numpy<1.25,>=1.21", - "opencv_python", - "pygame", - "pysubs2", - "PyAudio"], - url="https://github.com/ree1261/pyvidplayer2", - platforms=["windows"], - keywords=["pygame", "video", "playback"], -) \ No newline at end of file diff --git a/pyvidplayer2/pyvidplayer2/subtitles.py b/pyvidplayer2/subtitles.py similarity index 100% rename from pyvidplayer2/pyvidplayer2/subtitles.py rename to pyvidplayer2/subtitles.py diff --git a/pyvidplayer2/pyvidplayer2/video.py b/pyvidplayer2/video.py similarity index 100% rename from pyvidplayer2/pyvidplayer2/video.py rename to pyvidplayer2/video.py diff --git a/pyvidplayer2/pyvidplayer2/video_player.py b/pyvidplayer2/video_player.py similarity index 100% rename from pyvidplayer2/pyvidplayer2/video_player.py rename to pyvidplayer2/video_player.py diff --git a/pyvidplayer2/pyvidplayer2/video_pygame.py b/pyvidplayer2/video_pygame.py similarity index 100% rename from pyvidplayer2/pyvidplayer2/video_pygame.py rename to pyvidplayer2/video_pygame.py diff --git a/pyvidplayer2/pyvidplayer2/video_pyglet.py b/pyvidplayer2/video_pyglet.py similarity index 100% rename from pyvidplayer2/pyvidplayer2/video_pyglet.py rename to pyvidplayer2/video_pyglet.py diff --git a/pyvidplayer2/pyvidplayer2/video_pyqt.py b/pyvidplayer2/video_pyqt.py similarity index 100% rename from pyvidplayer2/pyvidplayer2/video_pyqt.py rename to pyvidplayer2/video_pyqt.py diff --git a/pyvidplayer2/pyvidplayer2/video_tkinter.py b/pyvidplayer2/video_tkinter.py similarity index 100% rename from pyvidplayer2/pyvidplayer2/video_tkinter.py rename to pyvidplayer2/video_tkinter.py diff --git a/pyvidplayer2/pyvidplayer2/webcam.py b/pyvidplayer2/webcam.py similarity index 100% rename from pyvidplayer2/pyvidplayer2/webcam.py rename to pyvidplayer2/webcam.py