Skip to content

Commit 270f48d

Browse files
Add build_executables.py script and requirements.txt
- Introduced a new script `build_executables.py` for building platform-specific executables using PyInstaller. - Implemented functions for cleaning build directories, handling retries on directory removal, and determining executable names based on the operating system. - Added `requirements.txt` to specify dependencies: PyInstaller, tk, pillow, and packaging. - Updated README.md to reflect recent changes and improvements in the application. new featues: ## Recent Updates: Multi-File Processing Support The GUI application has been enhanced with batch processing capabilities. Here are the key improvements: ### New Features 1. **Multiple File Selection** - Users can now select multiple files simultaneously - First selected file is displayed in the UI for reference 2. **Simplified Output Handling** - Single output directory selection for all files - Automatic file naming with "_injected" suffix 3. **Batch Processing** - Sequential processing of all selected files - Robust error handling: individual failures don't stop the batch - Progress tracking with status messages ### Technical Implementation The changes were implemented in `spatialmedia/gui.py`: ```python # Enable multiple file selection self.open_options["multiple"] = True # Process multiple files for input_file in self.all_files: output_file = os.path.join( os.path.dirname(self.save_file), f"{split_filename[0]}_injected{split_filename[1]}" ) metadata_utils.inject_metadata(input_file, output_file, metadata, console.append) ``` These updates significantly improve workflow efficiency when processing multiple videos.
1 parent 0ac9211 commit 270f48d

File tree

3 files changed

+90
-38
lines changed

3 files changed

+90
-38
lines changed

README.md

Lines changed: 0 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -7,41 +7,3 @@ A collection of specifications and tools for 360° video and spatial audio, i
77
- [Spherical Video V2](docs/spherical-video-v2-rfc.md) metadata specification
88
- [VR180 Video Format](docs/vr180.md) VR180 video format
99
- [Spatial Media tools](spatialmedia/) for injecting spatial media metadata in media files
10-
11-
## Recent Updates: Multi-File Processing Support
12-
13-
The GUI application has been enhanced with batch processing capabilities. Here are the key improvements:
14-
15-
### New Features
16-
17-
1. **Multiple File Selection**
18-
- Users can now select multiple files simultaneously
19-
- First selected file is displayed in the UI for reference
20-
21-
2. **Simplified Output Handling**
22-
- Single output directory selection for all files
23-
- Automatic file naming with "_injected" suffix
24-
25-
3. **Batch Processing**
26-
- Sequential processing of all selected files
27-
- Robust error handling: individual failures don't stop the batch
28-
- Progress tracking with status messages
29-
30-
### Technical Implementation
31-
32-
The changes were implemented in `spatialmedia/gui.py`:
33-
34-
```python
35-
# Enable multiple file selection
36-
self.open_options["multiple"] = True
37-
38-
# Process multiple files
39-
for input_file in self.all_files:
40-
output_file = os.path.join(
41-
os.path.dirname(self.save_file),
42-
f"{split_filename[0]}_injected{split_filename[1]}"
43-
)
44-
metadata_utils.inject_metadata(input_file, output_file, metadata, console.append)
45-
```
46-
47-
These updates significantly improve workflow efficiency when processing multiple videos.

build_executables.py

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
#!/usr/bin/env python3
2+
import os
3+
import sys
4+
import time
5+
import platform
6+
import subprocess
7+
import shutil
8+
9+
def get_platform_name():
10+
"""Get standardized platform name"""
11+
if sys.platform.startswith('win'):
12+
return 'windows'
13+
elif sys.platform.startswith('darwin'):
14+
return 'macos'
15+
elif sys.platform.startswith('linux'):
16+
return 'linux'
17+
return sys.platform
18+
19+
def retry_rmtree(directory_name, max_retries=3, delay=1):
20+
"""Retry removing directory tree with multiple attempts"""
21+
for attempt in range(max_retries):
22+
try:
23+
if os.path.exists(directory_name):
24+
shutil.rmtree(directory_name)
25+
return True
26+
except PermissionError as error:
27+
if attempt == max_retries - 1:
28+
print(f"Warning: Could not remove {directory_name}: {error}")
29+
return False
30+
print(f"Retrying removal of {directory_name} in {delay} seconds...")
31+
time.sleep(delay)
32+
return False
33+
34+
def clean_build_directories():
35+
"""Clean up build directories"""
36+
directories_to_clean = ['build', 'dist']
37+
for directory_name in directories_to_clean:
38+
if not retry_rmtree(directory_name):
39+
print(f"Warning: Proceeding without cleaning {directory_name}")
40+
41+
def get_executable_name():
42+
"""Get platform-specific executable name"""
43+
platform_name = get_platform_name()
44+
if platform_name == 'windows':
45+
return 'Spatial Media Metadata Injector.exe'
46+
elif platform_name == 'macos':
47+
return 'Spatial Media Metadata Injector.app'
48+
else:
49+
return 'Spatial Media Metadata Injector'
50+
51+
def build_executable():
52+
"""Build the executable for the current platform"""
53+
# Clean previous builds
54+
try:
55+
clean_build_directories()
56+
except Exception as error:
57+
print(f"Warning: Error during cleanup: {error}")
58+
print("Attempting to continue with build...")
59+
60+
# Get the specification file path
61+
specification_file = os.path.join('spatialmedia', 'spatial_media_metadata_injector.spec')
62+
63+
# Build command
64+
command = ['pyinstaller', '--clean', specification_file]
65+
66+
try:
67+
subprocess.check_call(command)
68+
platform_name = get_platform_name()
69+
exe_name = get_executable_name()
70+
print(f"Successfully built executable for {platform_name}")
71+
72+
# Show output location
73+
print(f"Output: ./dist/{exe_name}")
74+
75+
# Set executable permissions for Unix-like systems
76+
if platform_name in ('linux', 'macos'):
77+
output_path = os.path.join('dist', exe_name)
78+
if os.path.exists(output_path):
79+
os.chmod(output_path, 0o755)
80+
81+
except subprocess.CalledProcessError as error:
82+
print(f"Error building executable: {error}")
83+
sys.exit(1)
84+
85+
if __name__ == "__main__":
86+
build_executable()

requirements.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
PyInstaller
2+
tk
3+
pillow
4+
packaging

0 commit comments

Comments
 (0)