Advertisement
lildazeez
Oct 29th, 2024
15
1
Never
This is comment for paste Untitled
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import obspython as obs
  2. from shutil import move
  3. import os
  4. import time
  5. import logging
  6. from typing import Dict, Optional
  7. import re
  8.  
  9. class VODMover:
  10. def __init__(self):
  11. # Output paths and search strings with default values
  12. self.output_paths: Dict[str, str] = {
  13. "anythingelse": "D:/vods/anything-else",
  14. "bridges": "D:/vods/bridges",
  15. "destinystudio": "D:/vods/destiny-stream",
  16. "saturdaymorning": "D:/vods/saturday-morning"
  17. }
  18.  
  19. # Initialize logging
  20. self.setup_logging()
  21.  
  22. def setup_logging(self) -> None:
  23. """Set up logging configuration"""
  24. log_file = "obs_recording_move.log"
  25. logging.basicConfig(
  26. level=logging.INFO,
  27. format="%(asctime)s - %(levelname)s - %(message)s",
  28. handlers=[
  29. logging.FileHandler(log_file),
  30. logging.StreamHandler() # Also log to console
  31. ]
  32. )
  33. self.logger = logging.getLogger(__name__)
  34.  
  35. def move_recording(self, recording_path: str) -> None:
  36. """
  37. Move recording to appropriate folder based on filename patterns
  38. """
  39. if not recording_path or not os.path.exists(recording_path):
  40. self.logger.error(f"Invalid recording path: {recording_path}")
  41. return
  42.  
  43. try:
  44. filename = os.path.basename(recording_path).lower()
  45. destination = self._get_destination_folder(filename)
  46.  
  47. if destination:
  48. self._perform_move(recording_path, destination)
  49. else:
  50. self.logger.warning(f"No matching folder found for: {filename}")
  51. # Move to anything-else folder as fallback
  52. self._perform_move(recording_path, self.output_paths["anythingelse"])
  53.  
  54. except Exception as e:
  55. self.logger.error(f"Error processing recording {recording_path}: {str(e)}")
  56.  
  57. def _get_destination_folder(self, filename: str) -> Optional[str]:
  58. """
  59. Determine destination folder based on filename patterns
  60. """
  61. patterns = {
  62. "bridges": r"bridge|bridges",
  63. "destinystudio": r"destiny|studio",
  64. "saturdaymorning": r"saturday|morning|weekend"
  65. }
  66.  
  67. for key, pattern in patterns.items():
  68. if re.search(pattern, filename, re.IGNORECASE):
  69. return self.output_paths[key]
  70.  
  71. return None
  72.  
  73. def _perform_move(self, source: str, destination: str) -> None:
  74. """
  75. Perform the actual file move operation
  76. """
  77. if not os.path.exists(destination):
  78. os.makedirs(destination, exist_ok=True)
  79. self.logger.info(f"Created destination directory: {destination}")
  80.  
  81. try:
  82. # Wait for file to be fully written
  83. time.sleep(5)
  84.  
  85. # Get destination filepath
  86. dest_path = os.path.join(destination, os.path.basename(source))
  87.  
  88. # Handle existing files
  89. if os.path.exists(dest_path):
  90. base, ext = os.path.splitext(dest_path)
  91. counter = 1
  92. while os.path.exists(f"{base}_{counter}{ext}"):
  93. counter += 1
  94. dest_path = f"{base}_{counter}{ext}"
  95.  
  96. move(source, dest_path)
  97. self.logger.info(f"Successfully moved {source} to {dest_path}")
  98.  
  99. except Exception as e:
  100. self.logger.error(f"Failed to move file {source}: {str(e)}")
  101.  
  102. # Global instance of VODMover
  103. vod_mover = VODMover()
  104.  
  105. def script_description():
  106. """Return the script description for OBS"""
  107. return "Automatically moves VOD recordings to categorized folders based on filename patterns"
  108.  
  109. def script_load(settings):
  110. """Hook stop recording signal on script load"""
  111. signal_handler = obs.obs_output_get_signal_handler(
  112. obs.obs_frontend_get_recording_output()
  113. )
  114. obs.signal_handler_connect(signal_handler, "stop", on_recording_stop)
  115.  
  116. def script_update(settings):
  117. """Update paths when settings are changed"""
  118. global vod_mover
  119.  
  120. # Update paths from OBS settings
  121. vod_mover.output_paths = {
  122. "anythingelse": obs.obs_data_get_string(settings, "anything_else_path"),
  123. "bridges": obs.obs_data_get_string(settings, "bridges_path"),
  124. "destinystudio": obs.obs_data_get_string(settings, "destiny_path"),
  125. "saturdaymorning": obs.obs_data_get_string(settings, "saturday_path")
  126. }
  127.  
  128. def script_properties():
  129. """Define properties for OBS interface"""
  130. props = obs.obs_properties_create()
  131.  
  132. # Add path properties for each category
  133. obs.obs_properties_add_path(
  134. props, "anything_else_path",
  135. "Anything Else Path",
  136. obs.OBS_PATH_DIRECTORY,
  137. "", "D:/vods/anything-else"
  138. )
  139. obs.obs_properties_add_path(
  140. props, "bridges_path",
  141. "Bridges Path",
  142. obs.OBS_PATH_DIRECTORY,
  143. "", "D:/vods/bridges"
  144. )
  145. obs.obs_properties_add_path(
  146. props, "destiny_path",
  147. "Destiny Studio Path",
  148. obs.OBS_PATH_DIRECTORY,
  149. "", "D:/vods/destiny-stream"
  150. )
  151. obs.obs_properties_add_path(
  152. props, "saturday_path",
  153. "Saturday Morning Path",
  154. obs.OBS_PATH_DIRECTORY,
  155. "", "D:/vods/saturday-morning"
  156. )
  157.  
  158. return props
  159.  
  160. def on_recording_stop(calldata):
  161. """Handle recording stop event"""
  162. try:
  163. recording_path = obs.obs_frontend_get_last_recording()
  164. vod_mover.move_recording(recording_path)
  165. except Exception as e:
  166. logging.error(f"Error in recording stop handler: {str(e)}")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement