Skip to content

Commit c69350d

Browse files
committed
support macos in progress
1 parent 53e502c commit c69350d

9 files changed

+257
-68
lines changed

.DS_Store

6 KB
Binary file not shown.

Matrix-Windows.spec

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# -*- mode: python ; coding: utf-8 -*-
2+
3+
4+
block_cipher = None
5+
6+
7+
a = Analysis(
8+
['ascii12.py'],
9+
pathex=[],
10+
binaries=[('I:\\ascii\\matrix.ico', '.')],
11+
datas=[('I:\\ascii\\matrix.ico', '.')],
12+
hiddenimports=[],
13+
hookspath=[],
14+
hooksconfig={},
15+
runtime_hooks=[],
16+
excludes=[],
17+
win_no_prefer_redirects=False,
18+
win_private_assemblies=False,
19+
cipher=block_cipher,
20+
noarchive=False,
21+
)
22+
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
23+
splash = Splash(
24+
'Matrix.PNG',
25+
binaries=a.binaries,
26+
datas=a.datas,
27+
text_pos=None,
28+
text_size=12,
29+
minify_script=True,
30+
always_on_top=True,
31+
)
32+
33+
exe = EXE(
34+
pyz,
35+
a.scripts,
36+
a.binaries,
37+
a.zipfiles,
38+
a.datas,
39+
splash,
40+
splash.binaries,
41+
[],
42+
name='Matrix',
43+
debug=False,
44+
bootloader_ignore_signals=False,
45+
strip=False,
46+
upx=True,
47+
upx_exclude=[],
48+
runtime_tmpdir=None,
49+
console=False,
50+
disable_windowed_traceback=False,
51+
argv_emulation=False,
52+
target_arch=None,
53+
codesign_identity=None,
54+
entitlements_file=None,
55+
icon=['I:\\ascii\\matrix.ico'],
56+
)

Matrix-macos.spec

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
# -*- mode: python ; coding: utf-8 -*-
2+
#from kivy.tools.packaging.pyinstaller_hooks import get_deps_all, hookspath, runtime_hooks, get_deps_minimal
3+
from PyInstaller.utils.hooks import collect_data_files
4+
import sys
5+
import os.path
6+
7+
block_cipher = None
8+
9+
version_python = f'{sys.version[0]}.{sys.version_info[1]}'
10+
11+
if version_python == '3.10':
12+
pathex=['/opt/homebrew/lib/python3.10/site-packages/']
13+
target_arch='arm64'
14+
else :
15+
if version_python == '3.9':
16+
pathex=['/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/']
17+
target_arch='x86_64'
18+
19+
name=f'Matrix_{target_arch}.app'
20+
21+
a = Analysis(
22+
[
23+
'ascii12.py',
24+
],
25+
pathex=pathex,
26+
binaries=[],
27+
datas=[('matrix-macos.icns', '.'), ('matrix-linux.png', '.')],
28+
hiddenimports=[],
29+
hookspath=[],#hookspath(),
30+
hooksconfig={},
31+
runtime_hooks=[],#runtime_hooks(),
32+
excludes=[],
33+
win_no_prefer_redirects=False,
34+
win_private_assemblies=False,
35+
cipher=block_cipher,
36+
noarchive=False,
37+
#**get_deps_all(),
38+
)
39+
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
40+
41+
exe = EXE(
42+
pyz,
43+
a.scripts,
44+
[],
45+
exclude_binaries=True,
46+
name='Matrix',
47+
debug=False,
48+
bootloader_ignore_signals=False,
49+
strip=False,
50+
upx=True,
51+
console=False,
52+
disable_windowed_traceback=True,
53+
argv_emulation=False,
54+
target_arch=target_arch,
55+
codesign_identity=None,
56+
entitlements_file=None,
57+
icon=['matrix-macos.icns'],
58+
)
59+
60+
coll = COLLECT(
61+
exe,
62+
a.binaries,
63+
a.zipfiles,
64+
a.datas,
65+
strip=False,
66+
upx=True,
67+
upx_exclude=[],
68+
name='Matrix',
69+
)
70+
app = BUNDLE(
71+
coll,
72+
name=name,
73+
icon="matrix-macos.icns",
74+
bundle_identifier="com.matrix.bitscripts",
75+
info_plist={
76+
"CFBundleShortVersionString": "1.0.0",
77+
'NSPrincipalClass': 'NSApplication',
78+
'NSAppleScriptEnabled': False,
79+
'NSCameraUsageDescription': "This app requires camera access to capture your face photos to send you in Matrix.",
80+
'Application is background only': False,
81+
'AllowCacheDelete': True,
82+
'AllowPersonalCaching': True,
83+
"CFBundleDocumentTypes": [
84+
{
85+
'CFBundleTypeIconFile': 'matrix-macos.icns',
86+
"CFBundleTypeName": 'Package Icon',
87+
'CFBundleTypeRole': 'Editor',
88+
"CFBundleTypeOSTypes": ["ICON"],
89+
},
90+
{
91+
'CFBundleTypeIconFile': 'matrix-linux.png',
92+
"CFBundleTypeName": 'Image use in project',
93+
'CFBundleTypeRole': 'Editor',
94+
"CFBundleTypeOSTypes": ["IMAGE"],
95+
},
96+
{
97+
"CFBundleTypeExtensions": ["py", "pyw"],
98+
"CFBundleTypeName": "Python Scripts",
99+
"CFBundleTypeRole": "Editor",
100+
"CFBundleTypeOSTypes": ["TEXT"],
101+
},
102+
{
103+
"CFBundleTypeExtensions": ["txt"],
104+
"CFBundleTypeName": "Text",
105+
"CFBundleTypeRole": "Editor",
106+
"CFBundleTypeOSTypes": ["TEXT"],
107+
},
108+
]
109+
},
110+
)

ascii18.py

Lines changed: 78 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from PyQt6.QtCore import Qt, QTimer
1212
from PyQt6.QtGui import QCloseEvent, QIcon, QImage, QKeyEvent, QPixmap, QColor, QPainter, QFont, QFontDatabase
1313
from PyQt6.QtWidgets import QApplication, QMainWindow, QLabel, QVBoxLayout, QWidget, QComboBox, QPushButton, QFrame
14-
if sys.platform == 'win32':
14+
if sys.platform == 'win32' or sys.platform == 'darwin':
1515
import qdarktheme
1616

1717
class CameraApp(QMainWindow):
@@ -100,24 +100,24 @@ def get_available_cameras(self):
100100

101101

102102
def get_cameras_mac(self):
103-
# print("entre dans get_cameras_mac()")
104103
try:
105-
import Quartz
104+
from AVFoundation import AVCaptureDevice
105+
106106
except ImportError:
107-
self.label.setText("Installez pyobjc avec 'pip install pyobjc'")
107+
print("Installez pyobjc avec 'pip install pyobjc'")
108108
return {}
109109

110110
camera_indices = []
111111
camera_names = []
112112

113-
for index, device in enumerate(Quartz.IORegistryIteratorCreateForMatchingService(Quartz.kIOMasterPortDefault, Quartz.CFDictionaryCreate(None, (Quartz.kIOUSBDeviceClassName,), (True,), 1))):
114-
camera_name = Quartz.IORegistryEntryGetName(device)
115-
if "infrared" in camera_name.lower() or "ir" in camera_name.lower():
116-
continue # Ignore the infrared camera
113+
devices = AVCaptureDevice.devicesWithMediaType_('vide')
114+
for device_index, device_name in enumerate(devices):
115+
camera_name = device_name.localizedName().cString()
117116
camera_names.append(camera_name)
118-
camera_indices.append(index)
119-
return camera_names, camera_indices
117+
camera_indices.append(device_index)
120118

119+
return camera_names, camera_indices
120+
121121
def get_cameras_windows(self):
122122
# print("entre dans get_cameras_windows()")
123123
try:
@@ -243,7 +243,17 @@ def run(self, virtual_frame):
243243
except Exception as e:
244244
print(f"Erreur dans virtual_camera.create_virtual_camera: {e}")
245245
pass
246-
self.old_frame = virtual_frame_resized
246+
elif sys.platform.startswith("darwin"):
247+
with pyvirtualcam.Camera(width=1280, height=720, fps=30) as cam:
248+
try:
249+
virtual_frame = self.virtual_frame
250+
virtual_frame_resized = self.resize_image(virtual_frame, 1280, 720)
251+
cam.send(virtual_frame_resized)
252+
cam.sleep_until_next_frame()
253+
except Exception as e:
254+
print(f"Erreur dans virtual_camera.create_virtual_camera: {e}")
255+
pass
256+
self.old_frame = virtual_frame_resized
247257
def resize_image(self, image, width, height):
248258
resized_image = cv2.resize(image, (width, height))
249259
return resized_image
@@ -535,11 +545,11 @@ def __init__(self):
535545
except (ImportError, AttributeError, OSError):
536546
pass
537547

538-
self.counter = 0
539-
self.timer_counter = QTimer(self)
540-
self.image_label = QLabel()
541-
self.timer_counter.timeout.connect(self.update_counter)
542-
self.timer_counter.start(1000)
548+
# self.counter = 0
549+
# self.timer_counter = QTimer(self)
550+
# self.image_label = QLabel()
551+
# self.timer_counter.timeout.connect(self.update_counter)
552+
# self.timer_counter.start(1000)
543553

544554
self.cap = None
545555
self.timer_capture = QTimer()
@@ -608,67 +618,67 @@ def update_image_label(self, virtual_frame):
608618
print(f"Erreur dans matrix.update_virtual_frame: {e}")
609619
message = False
610620

611-
def update_counter(self):
612-
# print("entre dans matrix.update_counter()\n")
613-
self.counter += 1
614-
self.counter_string = str(self.counter)
621+
# def update_counter(self):
622+
# # print("entre dans matrix.update_counter()\n")
623+
# self.counter += 1
624+
# self.counter_string = str(self.counter)
615625

616-
if random.randint(0, 9) % 2 == 0:
617-
self.counter_string = self.counter_string.replace("0", "¦")
618-
if random.randint(0, 9) % 2 == 0:
619-
self.counter_string = self.counter_string.replace("1","§")
620-
if random.randint(0, 9) % 2 == 0:
621-
self.counter_string = self.counter_string.replace("2", "¨")
622-
if random.randint(0, 9) % 2 == 0:
623-
self.counter_string = self.counter_string.replace("3", "©")
624-
if random.randint(0, 9) % 2 == 0:
625-
self.counter_string = self.counter_string.replace("4", "ª")
626-
if random.randint(0, 9) % 2 == 0:
627-
self.counter_string = self.counter_string.replace("5", "«")
628-
if random.randint(0, 9) % 2 == 0:
629-
self.counter_string = self.counter_string.replace("6", "¬")
630-
if random.randint(0, 9) % 2 == 0:
631-
self.counter_string = self.counter_string.replace("8", "®")
632-
if random.randint(0, 9) % 2 == 0:
633-
self.counter_string = self.counter_string.replace("9", "¯")
626+
# if random.randint(0, 9) % 2 == 0:
627+
# self.counter_string = self.counter_string.replace("0", "¦")
628+
# if random.randint(0, 9) % 2 == 0:
629+
# self.counter_string = self.counter_string.replace("1","§")
630+
# if random.randint(0, 9) % 2 == 0:
631+
# self.counter_string = self.counter_string.replace("2", "¨")
632+
# if random.randint(0, 9) % 2 == 0:
633+
# self.counter_string = self.counter_string.replace("3", "©")
634+
# if random.randint(0, 9) % 2 == 0:
635+
# self.counter_string = self.counter_string.replace("4", "ª")
636+
# if random.randint(0, 9) % 2 == 0:
637+
# self.counter_string = self.counter_string.replace("5", "«")
638+
# if random.randint(0, 9) % 2 == 0:
639+
# self.counter_string = self.counter_string.replace("6", "¬")
640+
# if random.randint(0, 9) % 2 == 0:
641+
# self.counter_string = self.counter_string.replace("8", "®")
642+
# if random.randint(0, 9) % 2 == 0:
643+
# self.counter_string = self.counter_string.replace("9", "¯")
634644

635645

636-
pixmap = QPixmap(1280, 720) # Créez un QPixmap de la taille souhaitée
637-
pixmap.fill(QColor(0,0,0)) # Remplissez-le avec une couleur transparente
646+
# pixmap = QPixmap(1280, 720) # Créez un QPixmap de la taille souhaitée
647+
# pixmap.fill(QColor(0,0,0)) # Remplissez-le avec une couleur transparente
638648

639-
painter = QPainter(pixmap)
649+
# painter = QPainter(pixmap)
640650

641-
font_id = QFontDatabase.addApplicationFont(self.font_path)
642-
if font_id < 0: print("Error")
643-
families = QFontDatabase.applicationFontFamilies(font_id)
644-
painter.setFont(QFont(families[0], 40))
645-
painter.setPen(QColor("#008800"))
651+
# font_id = QFontDatabase.addApplicationFont(self.font_path)
652+
# if font_id < 0: print("Error")
653+
# families = QFontDatabase.applicationFontFamilies(font_id)
654+
# painter.setFont(QFont(families[0], 40))
655+
# painter.setPen(QColor("#008800"))
646656

647-
self.counter_txt = "C O M P T E U R : "
657+
# self.counter_txt = "C O M P T E U R : "
648658

649-
if random.randint(0, 9) % 2 == 0:
650-
self.counter_txt = self.counter_txt.replace("C", "Ý")
651-
if random.randint(0, 9) % 2 == 0:
652-
self.counter_txt = self.counter_txt.replace("M", "ç")
653-
if random.randint(0, 9) % 2 == 0:
654-
self.counter_txt = self.counter_txt.replace("P", "ê")
655-
if random.randint(0, 9) % 2 == 0:
656-
self.counter_txt = self.counter_txt.replace("T", "î")
657-
if random.randint(0, 9) % 2 == 0:
658-
self.counter_txt = self.counter_txt.replace("E", "ß")
659-
if random.randint(0, 9) % 2 == 0:
660-
self.counter_txt = self.counter_txt.replace("U", "ï")
661-
if random.randint(0, 9) % 2 == 0:
662-
self.counter_txt = self.counter_txt.replace("R", "ì")
659+
# if random.randint(0, 9) % 2 == 0:
660+
# self.counter_txt = self.counter_txt.replace("C", "Ý")
661+
# if random.randint(0, 9) % 2 == 0:
662+
# self.counter_txt = self.counter_txt.replace("M", "ç")
663+
# if random.randint(0, 9) % 2 == 0:
664+
# self.counter_txt = self.counter_txt.replace("P", "ê")
665+
# if random.randint(0, 9) % 2 == 0:
666+
# self.counter_txt = self.counter_txt.replace("T", "î")
667+
# if random.randint(0, 9) % 2 == 0:
668+
# self.counter_txt = self.counter_txt.replace("E", "ß")
669+
# if random.randint(0, 9) % 2 == 0:
670+
# self.counter_txt = self.counter_txt.replace("U", "ï")
671+
# if random.randint(0, 9) % 2 == 0:
672+
# self.counter_txt = self.counter_txt.replace("R", "ì")
663673

664674

665-
# print(self.counter_txt + self.counter_string)
675+
# # print(self.counter_txt + self.counter_string)
666676

667-
painter.drawText(pixmap.rect(), Qt.AlignmentFlag.AlignCenter, self.counter_txt + self.counter_string)
677+
# painter.drawText(pixmap.rect(), Qt.AlignmentFlag.AlignCenter, self.counter_txt + self.counter_string)
668678

669-
painter.end()
670-
# if random.randint(0, 9) % 3 == 0:
671-
# self.image_label.setPixmap(pixmap)
679+
# painter.end()
680+
# if random.randint(0, 9) % 3 == 0:
681+
# self.image_label.setPixmap(pixmap)
672682

673683

674684
def setCameraIndex(self, index):
@@ -793,6 +803,8 @@ def capture_frame(self):
793803
app = QApplication([])
794804
if sys.platform == 'win32':
795805
qdarktheme.setup_theme("auto", custom_colors={"primary": "#00B294"})
806+
if sys.platform == 'darwin':
807+
qdarktheme.setup_theme("auto")
796808
matrix = Matrix()
797809
camera_app = CameraApp(matrix)
798810
matrix.hide()

matrix-macos-bundle.icns

938 KB
Binary file not shown.

matrix-macos.icns

120 KB
Binary file not shown.

requirements-linux.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@ Pillow
44
pyudev
55
v4l2py
66
thread6
7-
pyqt6
7+
pyqt6
8+
pyvirtualcam

requirements-macos.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
numpy
2+
opencv-python-headless
3+
Pillow
4+
pyudev
5+
thread6
6+
pyqt6
7+
pyqtdarktheme
8+
pyobjc
9+
pyvirtualcam @ git+https://github.com/letmaik/pyvirtualcam

0 commit comments

Comments
 (0)