Browse Source

#42

feature/042
みてるぞ 2 weeks ago
parent
commit
a8239f3de3
1 changed files with 46 additions and 85 deletions
  1. +46
    -85
      main.py

+ 46
- 85
main.py View File

@@ -857,8 +857,11 @@ class Broadcast:




class Video (GameObject): class Video (GameObject):
cap: VideoCapture | None
current: Surface | None
fps: int fps: int
pausing: bool = False
path: str
pausing: bool = False
sound: Sound | None sound: Sound | None
surfaces: list[Surface] surfaces: list[Surface]


@@ -868,86 +871,19 @@ class Video (GameObject):
path: str, path: str,
): ):
super ().__init__ (game) super ().__init__ (game)
self.pausing = False
(self.surfaces, self.fps) = self._create_surfaces (path)
self.path = path
self.cap = None
self.current = None
self.sound = self._create_sound (path) self.sound = self._create_sound (path)
self.stop () self.stop ()


def _create_sound (
self,
path: str,
) -> Sound | None:
bytes_io = BytesIO ()
try:
from pydub import AudioSegment
audio = AudioSegment.from_file (path, format = path.split ('.')[-1])
except ModuleNotFoundError:
return None
audio.export (bytes_io, format = 'wav')
bytes_io.seek (0)
return pygame.mixer.Sound (bytes_io)

def _create_surfaces (
self,
path: str,
) -> tuple[list[Surface], int]:
cap = self._load (path)
surfaces: list[Surface] = []
if cap is None:
return ([], FPS)
fps = int (cap.get (cv2.CAP_PROP_FPS))
while cap.isOpened ():
frame = self._read_frame (cap)
if frame is None:
break
surfaces.append (self._convert_to_surface (frame))
new_surfaces: list[Surface] = []
for i in range (len (surfaces) * FPS // fps):
new_surfaces.append (surfaces[i * fps // FPS])
return (new_surfaces, fps)

def _load (
self,
path: str,
) -> VideoCapture | None:
"""
OpenCV で動画を読込む.
"""
cap = VideoCapture (path)
if cap.isOpened ():
return cap
return None

def _read_frame (
self,
cap: VideoCapture,
) -> np.ndarray | None:
"""
動画のフレームを読込む.
"""
ret: bool
frame: np.ndarray
(ret, frame) = cap.read ()
if ret:
return frame
return None

def _convert_to_surface (
self,
frame: np.ndarray,
) -> Surface:
frame = cv2.cvtColor (frame, cv2.COLOR_BGR2RGB)
frame_surface = pygame.surfarray.make_surface (frame)
frame_surface = pygame.transform.rotate (frame_surface, -90)
frame_surface = pygame.transform.flip (frame_surface, True, False)
return frame_surface

def play ( def play (
self, self,
) -> None: ) -> None:
self.enabled = True self.enabled = True
self.pausing = False
if self.sound is not None:
self.cap = VideoCapture (self.path)
self.frame = 0
if self.sound:
self.sound.play () self.sound.play ()


def stop ( def stop (
@@ -955,28 +891,53 @@ class Video (GameObject):
) -> None: ) -> None:
self.enabled = False self.enabled = False
self.frame = 0 self.frame = 0

def pause (
self,
) -> None:
self.pausing = True
if self.cap:
self.cap.release ()
self.cap = None


def redraw ( def redraw (
self, self,
) -> None: ) -> None:
surface = pygame.transform.scale (self.surfaces[self.frame], (self.width, self.height))
self.game.screen.blit (surface, (self.x, self.y))
if (not self.enabled) or (self.cap is None):
return
ret, frame = self.cap.read ()
if not ret:
self.stop ()
return
surf = self._convert_to_surface (frame)
surf = pygame.transform.scale (surf, (self.width, self.height))
self.game.screen.blit (surf, (self.x, self.y))
super ().redraw () super ().redraw ()


def update ( def update (
self, self,
) -> None: ) -> None:
if self.frame >= len (self.surfaces) - 1:
self.stop ()
if self.pausing:
self.frame -= 1
super ().update () super ().update ()


def _convert_to_surface (
self,
frame: np.ndarray,
) -> Surface:
frame = cv2.cvtColor (frame, cv2.COLOR_BGR2RGB)
frame_surface = pygame.surfarray.make_surface (frame)
frame_surface = pygame.transform.rotate (frame_surface, -90)
frame_surface = pygame.transform.flip (frame_surface, True, False)
return frame_surface

def _create_sound (
self,
path: str,
) -> Sound | None:
bytes_io = BytesIO ()
try:
from pydub import AudioSegment
audio = AudioSegment.from_file (path, format = path.split ('.')[-1])
except ModuleNotFoundError:
return None
audio.export (bytes_io, format = 'wav')
bytes_io.seek (0)
return pygame.mixer.Sound (bytes_io)



class NicoVideo (Video): class NicoVideo (Video):
def __init__ ( def __init__ (


Loading…
Cancel
Save