class Recordings

Stores one WebM narration recording for each slide.

Recording paths mirror slide paths. For example, slides/020-topic/010-example.md is stored as audio/020-topic/010-example.webm.

Nested Classes and Modules

class Normalizer

Normalizes recording loudness using measured gain and peak limiting.

class TooLarge

Raised when an uploaded recording exceeds MAXIMUM_SIZE = 128 * 1024 * 1024.

Definitions

CONTENT_TYPE = "audio/webm"

The media type produced by the browser recorder.

MAXIMUM_SIZE = 128 * 1024 * 1024

The maximum accepted recording size (128 MiB).

def initialize(root, maximum_size: MAXIMUM_SIZE)

Initialize the recording store.

Signature

parameter root String

The directory where recordings are stored.

parameter maximum_size Integer

Maximum accepted recording size in bytes.

Implementation

def initialize(root, maximum_size: MAXIMUM_SIZE)
	@root = File.expand_path(root)
	@maximum_size = maximum_size
end

attr :root

Signature

attribute String

The absolute recording root.

def relative_path(slide)

The recording path relative to #root for the given slide.

Signature

parameter slide Slide

The slide whose recording path is required.

returns String

Implementation

def relative_path(slide)
	slide.path.sub(/\.md\z/, ".webm")
end

def path(slide)

The absolute recording path for the given slide.

Signature

parameter slide Slide

The slide whose recording path is required.

returns String

Implementation

def path(slide)
	File.join(@root, relative_path(slide))
end

def exist?(slide)

Whether the slide has a recording.

Signature

parameter slide Slide

The slide to check.

returns Boolean

Implementation

def exist?(slide)
	File.file?(path(slide))
end

def read(slide)

Open the recording as an HTTP body.

Signature

parameter slide Slide

The slide to read.

returns Protocol::HTTP::Body::File | Nil

Implementation

def read(slide)
	if exist?(slide)
		Protocol::HTTP::Body::File.open(path(slide))
	end
end

def write(slide, body)

Write a recording atomically.

The request body is copied to a temporary file in the destination directory, then renamed over the existing recording only after the upload completes successfully.

Signature

parameter slide Slide

The slide being recorded.

parameter body Protocol::HTTP::Body::Readable

The uploaded recording.

returns String

The absolute destination path.

raises TooLarge

If the recording exceeds MAXIMUM_SIZE = 128 * 1024 * 1024.

Implementation

def write(slide, body)
	destination = path(slide)
	directory = File.dirname(destination)
	FileUtils.mkdir_p(directory)
	
	Tempfile.create(["presently-recording", ".webm"], directory, binmode: true) do |file|
		size = 0
		
		while chunk = body.read
			size += chunk.bytesize
			raise TooLarge, "Recording exceeds #{@maximum_size} bytes!" if size > @maximum_size
			
			file.write(chunk)
		end
		
		file.flush
		File.rename(file.path, destination)
	end
	
	return destination
end