@@ -147,9 +147,8 @@ def build_transformation_string(transformations)
147147
148148 # Handle overlay separately
149149 if key . to_s == "overlay" && ( value . is_a? ( Hash ) || value . respond_to? ( :to_h ) )
150- # Convert model object to hash if needed
151- overlay_hash = value . respond_to? ( :to_h ) ? value . to_h : value
152- raw_string = process_overlay ( overlay_hash )
150+ # Pass model object or hash directly to process_overlay
151+ raw_string = process_overlay ( value )
153152 if raw_string && !raw_string . strip . empty?
154153 parsed_transform_step << raw_string
155154 end
@@ -324,26 +323,37 @@ def path_join(parts, separator = "/")
324323
325324 # Process overlay transformation (full implementation)
326325 def process_overlay ( overlay )
327- return "" unless overlay . is_a? ( Hash )
328-
329- # Convert to symbol keys if needed
330- overlay_hash = { }
331- overlay . each { |k , v | overlay_hash [ k . to_sym ] = v }
332-
333- # Determine overlay type
334- if overlay_hash [ :text ] || overlay_hash [ "text" ]
335- process_text_overlay ( overlay_hash )
336- elsif overlay_hash [ :input ] || overlay_hash [ "input" ]
337- input = overlay_hash [ :input ] || overlay_hash [ "input" ]
338- if input . to_s . end_with? ( ".mp4" , ".webm" , ".mov" , ".avi" )
339- process_video_overlay ( overlay_hash )
340- elsif input . to_s . end_with? ( ".srt" , ".vtt" )
341- process_subtitle_overlay ( overlay_hash )
342- else
343- process_image_overlay ( overlay_hash )
344- end
345- elsif overlay_hash [ :color ] || overlay_hash [ "color" ]
346- process_solid_color_overlay ( overlay_hash )
326+ return "" unless overlay
327+
328+ # Get the overlay type - handle both model objects and hashes
329+ if overlay . respond_to? ( :type )
330+ # Model object - access type directly
331+ type = overlay . type
332+ overlay_obj = overlay
333+ elsif overlay . is_a? ( Hash )
334+ # Hash - look for type key
335+ type = overlay [ :type ] || overlay [ "type" ]
336+ # Convert to symbol keys if needed
337+ overlay_obj = { }
338+ overlay . each { |k , v | overlay_obj [ k . to_sym ] = v }
339+ else
340+ return ""
341+ end
342+
343+ return "" unless type
344+
345+ # Determine overlay type based on explicit type field
346+ case type . to_s
347+ when "text"
348+ process_text_overlay ( overlay_obj )
349+ when "image"
350+ process_image_overlay ( overlay_obj )
351+ when "video"
352+ process_video_overlay ( overlay_obj )
353+ when "subtitle"
354+ process_subtitle_overlay ( overlay_obj )
355+ when "solidColor"
356+ process_solid_color_overlay ( overlay_obj )
347357 else
348358 ""
349359 end
@@ -391,13 +401,13 @@ def uri_encode(str)
391401
392402 # Process text overlay
393403 def process_text_overlay ( overlay )
394- text = overlay [ :text ] || overlay [ "text" ] || ""
395- return "" if text . empty?
404+ text = safe_get ( overlay , :text )
405+ return "" unless text && ! text . to_s . empty?
396406
397407 parts = [ "l-text" ]
398408
399409 # Handle encoding using the processText function
400- encoding = overlay [ :encoding ] || overlay [ "encoding" ] || "auto"
410+ encoding = safe_get ( overlay , :encoding ) || "auto"
401411 parts << process_text ( text , encoding )
402412
403413 # Add other overlay properties (position, timing, transformations)
@@ -409,13 +419,13 @@ def process_text_overlay(overlay)
409419
410420 # Process image overlay
411421 def process_image_overlay ( overlay )
412- input = overlay [ :input ] || overlay [ "input" ] || ""
413- return "" if input . empty?
422+ input = safe_get ( overlay , :input )
423+ return "" unless input && ! input . to_s . empty?
414424
415425 parts = [ "l-image" ]
416426
417427 # Handle encoding using the process_input_path function
418- encoding = overlay [ :encoding ] || overlay [ "encoding" ] || "auto"
428+ encoding = safe_get ( overlay , :encoding ) || "auto"
419429 parts << process_input_path ( input , encoding )
420430
421431 # Add other overlay properties
@@ -427,13 +437,13 @@ def process_image_overlay(overlay)
427437
428438 # Process video overlay
429439 def process_video_overlay ( overlay )
430- input = overlay [ :input ] || overlay [ "input" ] || ""
431- return "" if input . empty?
440+ input = safe_get ( overlay , :input )
441+ return "" unless input && ! input . to_s . empty?
432442
433443 parts = [ "l-video" ]
434444
435445 # Handle encoding using the process_input_path function
436- encoding = overlay [ :encoding ] || overlay [ "encoding" ] || "auto"
446+ encoding = safe_get ( overlay , :encoding ) || "auto"
437447 parts << process_input_path ( input , encoding )
438448
439449 # Add other overlay properties
@@ -445,13 +455,13 @@ def process_video_overlay(overlay)
445455
446456 # Process subtitle overlay
447457 def process_subtitle_overlay ( overlay )
448- input = overlay [ :input ] || overlay [ "input" ] || ""
449- return "" if input . empty?
458+ input = safe_get ( overlay , :input )
459+ return "" unless input && ! input . to_s . empty?
450460
451461 parts = [ "l-subtitle" ]
452462
453463 # Handle encoding using the process_input_path function
454- encoding = overlay [ :encoding ] || overlay [ "encoding" ] || "auto"
464+ encoding = safe_get ( overlay , :encoding ) || "auto"
455465 parts << process_input_path ( input , encoding )
456466
457467 # Add other overlay properties
@@ -463,8 +473,8 @@ def process_subtitle_overlay(overlay)
463473
464474 # Process solid color overlay
465475 def process_solid_color_overlay ( overlay )
466- color = overlay [ :color ] || overlay [ "color" ] || ""
467- return "" if color . empty?
476+ color = safe_get ( overlay , :color )
477+ return "" unless color && ! color . to_s . empty?
468478
469479 parts = [ "l-image" , "i-ik_canvas" , "bg-#{ color } " ]
470480
@@ -478,21 +488,30 @@ def process_solid_color_overlay(overlay)
478488 # Safe property access that handles both hashes and model objects
479489 def safe_get ( obj , key )
480490 return nil unless obj
491+
492+ # For model objects, try method access first
493+ if obj . respond_to? ( key . to_sym )
494+ begin
495+ return obj . send ( key . to_sym )
496+ rescue StandardError
497+ # Fall through to hash access if method fails
498+ end
499+ end
500+
501+ # For hashes, try symbol first, then string
481502 if obj . respond_to? ( :[] )
482- # Try symbol first, then string for hash access
483503 begin
484- obj [ key . to_sym ]
504+ return obj [ key . to_sym ]
485505 rescue StandardError
486506 begin
487- obj [ key . to_s ]
507+ return obj [ key . to_s ]
488508 rescue StandardError
489- nil
509+ return nil
490510 end
491511 end
492- elsif obj . respond_to? ( key . to_sym )
493- # For model objects, use method access
494- obj . send ( key . to_sym )
495512 end
513+
514+ nil
496515 end
497516
498517 # Add overlay properties like position, timing, transformations (matching Node.js)
0 commit comments