diff --git a/build/lib/pygwin/record.py b/build/lib/pygwin/record.py new file mode 100644 index 0000000..c2c2d0f --- /dev/null +++ b/build/lib/pygwin/record.py @@ -0,0 +1,107 @@ +from contextlib import contextmanager +from pygwin._pg import pg as _pg +import moviepy.editor as mpe +from array import array +from PIL import Image +import numpy as np +import threading +import pyautogui +import tempfile +import pyaudio +import wave +import time +import sys +import cv2 +import os + +class record: + def __init__(self,win,audio=False): + self._isaudio = audio + self._surface = win + self.reset() + def reset(self): + self._run = False + self._fpss = [] + self._frames = [] + self._codec = cv2.VideoWriter_fourcc(*"mp4v") + if self._isaudio: + self._apy = pyaudio.PyAudio() + self._aframs = [] + self._astrm = self.apy.open(format=pyaudio.paInt16,channels=1, + rate=44100,input=True,frames_per_buffer=1024) + def start(self,newThread=True): + self._run = True + if self._isaudio: + def audiot(self): + while self._run: + self._aframs.append(self.astrm.read(1024)) + self._athread = threading.Thread(target=lambda:audiot(self)) + self._athread.start() + def main(self): + while self.run: + self._record() + if newThread: + self._thread = threading.Thread(target=lambda:main(self)) + self._thread.start() + else:main() + def _record(self): + if self._run: + try: + self._frames.append(self._surface) + self._fpss.append(self._surface.rawFps) + except: + pass + def render(self, path): + temp = tempfile.gettempdir() + if self.isaudio: + wavpath = os.path.join(temp, 'audio.wav') + wavfile = wave.open(wavpath, 'wb') + wavfile.setnchannels(1) + wavfile.setsampwidth(self._apy.get_sample_size(pyaudio.paInt16)) + wavfile.setframerate(44100) + af = [] + for i in self._aframs: + af.append(array('h',i)) + wavfile.writeframes(b''.join(af)) + wavfile.close() + + fps = 0 + for i in self._fpss: + fps += i + fps = fps/len(self._fpss) + if self._isaudio: + noaudiopath = os.path.join(temp, 'noaudio.mp4') + else: + noaudiopath = path + out = cv2.VideoWriter(noaudiopath,self._codec, + fps,self._surface.size) + for i in self._frames: + frame = np.array(_pg.surfarray.array3d(i).swapaxes(0,1)) + frame = cv2.cvtColor(frame,cv2.COLOR_BGR2RGB) + out.write(frame) + out.release() + + if self._isaudio: + videoclip = mpe.VideoFileClip(noaudiopath) + audioclip = mpe.AudioFileClip(wavpath) + new_audioclip = mpe.CompositeAudioClip([audioclip]) + videoclip.audio = new_audioclip + @contextmanager + def ss(): + with open(os.devnull, "w") as devnull: + oso = sys.stdout + sys.stdout = devnull + try:yield + finally:sys.stdout=oso + with ss(): + videoclip.write_videofile(path) + os.remove(noaudiopath) + os.remove(wavpath) + def stop(self): + self._run = False + try: + self._thread.join() + except: + pass + if self._isaudio: + self._athread.join() diff --git a/dist/pgw-0.0.4-py3.7.egg b/dist/pgw-0.0.4-py3.7.egg new file mode 100644 index 0000000..3b0747f Binary files /dev/null and b/dist/pgw-0.0.4-py3.7.egg differ diff --git a/setup.cfg b/setup.cfg index a9d2be4..ad78919 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = pgw -version = 0.0.3 +version = 0.0.4 author = themixray author_email = simindeymo@gmail.com description = Python Grapchical Window. diff --git a/setup.py b/setup.py index 468f619..57517ec 100644 --- a/setup.py +++ b/setup.py @@ -1,6 +1,8 @@ from setuptools import setup -setup(name='pgw',packages=['pygwin'],version='0.0.3',author='themixray', +setup(name='pgw',packages=['pygwin'],version='0.0.4',author='themixray', description='A library for creating Python applications.', - license='MIT',install_requires=['cython','pywin32','pygame', - 'inputs','pydub','wxPython','pyautogui']) + license='MIT',install_requires= + ['cython','pywin32','pygame','inputs', + 'pydub','wxPython','pyautogui','moviepy', + 'pipwin','wave','opencv-python']) diff --git a/src/pgw.egg-info/PKG-INFO b/src/pgw.egg-info/PKG-INFO index 63827af..84468b7 100644 --- a/src/pgw.egg-info/PKG-INFO +++ b/src/pgw.egg-info/PKG-INFO @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: pgw -Version: 0.0.3 +Version: 0.0.4 Summary: A library for creating Python applications. Home-page: https://github.com/themixray/pygwin Author: themixray @@ -8,24 +8,21 @@ Author-email: simindeymo@gmail.com License: MIT Project-URL: Bug Tracker, https://github.com/themixray/pygwin/issues Project-URL: Wiki, https://github.com/themixray/pygwin/wiki +Description:

+ PyGWin +

+

+ A library for creating Python applications. +

+ +

+ + Documentation + +

+ Platform: UNKNOWN Classifier: Programming Language :: Python :: 3 Classifier: License :: OSI Approved :: MIT License Classifier: Operating System :: OS Independent Description-Content-Type: text/markdown -License-File: LICENSE - -

- PyGWin -

-

- A library for creating Python applications. -

- -

- - Documentation - -

- - diff --git a/src/pgw.egg-info/SOURCES.txt b/src/pgw.egg-info/SOURCES.txt index 9fa79f3..86abac0 100644 --- a/src/pgw.egg-info/SOURCES.txt +++ b/src/pgw.egg-info/SOURCES.txt @@ -18,6 +18,7 @@ src/pygwin/image.py src/pygwin/keyboard.py src/pygwin/mixer.py src/pygwin/mouse.py +src/pygwin/record.py src/pygwin/rect.py src/pygwin/surface.py src/pygwin/tray.py diff --git a/src/pgw.egg-info/requires.txt b/src/pgw.egg-info/requires.txt index 569ce2e..a13bd06 100644 --- a/src/pgw.egg-info/requires.txt +++ b/src/pgw.egg-info/requires.txt @@ -5,3 +5,7 @@ inputs pydub wxPython pyautogui +moviepy +pipwin +wave +opencv-python diff --git a/src/pygwin/record.py b/src/pygwin/record.py new file mode 100644 index 0000000..c2c2d0f --- /dev/null +++ b/src/pygwin/record.py @@ -0,0 +1,107 @@ +from contextlib import contextmanager +from pygwin._pg import pg as _pg +import moviepy.editor as mpe +from array import array +from PIL import Image +import numpy as np +import threading +import pyautogui +import tempfile +import pyaudio +import wave +import time +import sys +import cv2 +import os + +class record: + def __init__(self,win,audio=False): + self._isaudio = audio + self._surface = win + self.reset() + def reset(self): + self._run = False + self._fpss = [] + self._frames = [] + self._codec = cv2.VideoWriter_fourcc(*"mp4v") + if self._isaudio: + self._apy = pyaudio.PyAudio() + self._aframs = [] + self._astrm = self.apy.open(format=pyaudio.paInt16,channels=1, + rate=44100,input=True,frames_per_buffer=1024) + def start(self,newThread=True): + self._run = True + if self._isaudio: + def audiot(self): + while self._run: + self._aframs.append(self.astrm.read(1024)) + self._athread = threading.Thread(target=lambda:audiot(self)) + self._athread.start() + def main(self): + while self.run: + self._record() + if newThread: + self._thread = threading.Thread(target=lambda:main(self)) + self._thread.start() + else:main() + def _record(self): + if self._run: + try: + self._frames.append(self._surface) + self._fpss.append(self._surface.rawFps) + except: + pass + def render(self, path): + temp = tempfile.gettempdir() + if self.isaudio: + wavpath = os.path.join(temp, 'audio.wav') + wavfile = wave.open(wavpath, 'wb') + wavfile.setnchannels(1) + wavfile.setsampwidth(self._apy.get_sample_size(pyaudio.paInt16)) + wavfile.setframerate(44100) + af = [] + for i in self._aframs: + af.append(array('h',i)) + wavfile.writeframes(b''.join(af)) + wavfile.close() + + fps = 0 + for i in self._fpss: + fps += i + fps = fps/len(self._fpss) + if self._isaudio: + noaudiopath = os.path.join(temp, 'noaudio.mp4') + else: + noaudiopath = path + out = cv2.VideoWriter(noaudiopath,self._codec, + fps,self._surface.size) + for i in self._frames: + frame = np.array(_pg.surfarray.array3d(i).swapaxes(0,1)) + frame = cv2.cvtColor(frame,cv2.COLOR_BGR2RGB) + out.write(frame) + out.release() + + if self._isaudio: + videoclip = mpe.VideoFileClip(noaudiopath) + audioclip = mpe.AudioFileClip(wavpath) + new_audioclip = mpe.CompositeAudioClip([audioclip]) + videoclip.audio = new_audioclip + @contextmanager + def ss(): + with open(os.devnull, "w") as devnull: + oso = sys.stdout + sys.stdout = devnull + try:yield + finally:sys.stdout=oso + with ss(): + videoclip.write_videofile(path) + os.remove(noaudiopath) + os.remove(wavpath) + def stop(self): + self._run = False + try: + self._thread.join() + except: + pass + if self._isaudio: + self._athread.join()