Much base work started
Some checks failed
CI / scan_ruby (push) Has been cancelled
CI / scan_js (push) Has been cancelled
CI / lint (push) Has been cancelled
CI / test (push) Has been cancelled
CI / system-test (push) Has been cancelled

This commit is contained in:
Dan Milne
2025-10-31 14:36:14 +11:00
parent 4a35bf6758
commit 88a906064f
97 changed files with 5333 additions and 2774 deletions

75
app/models/media_file.rb Normal file
View File

@@ -0,0 +1,75 @@
class MediaFile < ApplicationRecord
# Base class for all media files (Video, Audio, etc.)
# Uses Single Table Inheritance (STI) via the 'type' column
self.table_name = 'videos'
self.abstract_class = true
include Streamable
include Processable
# Common JSON stores for flexible metadata
store :fingerprints, accessors: [:xxhash64, :md5, :oshash, :phash]
store :media_metadata, accessors: [:duration, :codec, :bit_rate, :format]
# Common associations
belongs_to :work
belongs_to :storage_location
has_many :playback_sessions, dependent: :destroy
# Common validations
validates :filename, presence: true
validates :xxhash64, presence: true, uniqueness: { scope: :storage_location_id }
# Common scopes
scope :web_compatible, -> { where(web_compatible: true) }
scope :needs_transcoding, -> { where(web_compatible: false) }
scope :recent, -> { order(created_at: :desc) }
# Common delegations
delegate :display_title, to: :work, prefix: true, allow_nil: true
# Common instance methods
def display_title
work&.display_title || filename
end
def full_file_path
File.join(storage_location.path, filename)
end
def format_duration
return "Unknown" unless duration
hours = (duration / 3600).to_i
minutes = ((duration % 3600) / 60).to_i
seconds = (duration % 60).to_i
if hours > 0
"%d:%02d:%02d" % [hours, minutes, seconds]
else
"%d:%02d" % [minutes, seconds]
end
end
# Template method for subclasses to override
def web_stream_path
# Default implementation - subclasses can override for specific behavior
if transcoded_permanently? && transcoded_path && File.exist?(transcoded_full_path)
return transcoded_full_path
end
if transcoded_path && File.exist?(temp_transcoded_full_path)
return temp_transcoded_full_path
end
full_file_path if web_compatible?
end
def transcoded_full_path
return nil unless transcoded_path
File.join(storage_location.path, transcoded_path)
end
def temp_transcoded_full_path
return nil unless transcoded_path
File.join(Rails.root, 'tmp', 'transcodes', storage_location.id.to_s, transcoded_path)
end
end