Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 48 additions & 27 deletions .github/workflows/elixir.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.

name: Elixir CI

on:
Expand All @@ -22,42 +17,68 @@ jobs:

steps:
- uses: actions/checkout@v4

- name: Set up Elixir
uses: erlef/setup-beam@61e01a43a562a89bfc54c7f9a378ff67b03e4a21 # v1.16.0
with:
elixir-version: '1.18.3' # [Required] Define the Elixir version
otp-version: '27.3.4' # [Required] Define the Erlang/OTP version
- name: Restore dependencies cache
uses: actions/cache@v3

- name: Install and cache apt packages
uses: awalsh128/cache-apt-pkgs-action@v1
with:
path: deps
key: ${{ runner.os }}-mix-${{ hashFiles('**/mix.lock') }}
restore-keys: ${{ runner.os }}-mix-
- name: Install dependencies
run: mix deps.get
- name: Install additional tools
packages: fd-find ffmpeg zstd mediainfo
version: 1.0

- name: Cache ab-av1 binary
id: cache-ab-av1
uses: actions/cache@v4
with:
path: /usr/local/bin/ab-av1
key: ab-av1-v0.10.1

- name: Install ab-av1
if: steps.cache-ab-av1.outputs.cache-hit != 'true'
run: |
sudo apt-get update
sudo apt-get install -y fd-find ffmpeg zstd
# Install ab-av1 from GitHub releases
wget -O /tmp/ab-av1.tar.zst https://github.com/alexheretic/ab-av1/releases/download/v0.10.1/ab-av1-v0.10.1-x86_64-unknown-linux-musl.tar.zst
cd /tmp && zstd -d ab-av1.tar.zst && tar -xf ab-av1.tar
sudo mv ab-av1 /usr/local/bin/ab-av1
sudo chmod +x /usr/local/bin/ab-av1
- name: Set up PostgreSQL
uses: harmon758/postgresql-action@v1

- name: Restore dependencies cache
uses: actions/cache@v4
with:
postgresql version: '15'
postgresql db: reencodarr_test
postgresql user: postgres
postgresql password: postgres
- name: Wait for PostgreSQL
run: |
for i in {1..30}; do
pg_isready -h localhost -p 5432 -U postgres && break
sleep 1
done
path: deps
key: ${{ runner.os }}-mix-deps-${{ hashFiles('**/mix.lock') }}
restore-keys: ${{ runner.os }}-mix-deps-

- name: Restore build cache
uses: actions/cache@v4
with:
path: _build
key: ${{ runner.os }}-mix-build-${{ hashFiles('**/mix.lock') }}-${{ hashFiles('**/*.ex') }}-${{ hashFiles('**/*.exs') }}
restore-keys: |
${{ runner.os }}-mix-build-${{ hashFiles('**/mix.lock') }}-
${{ runner.os }}-mix-build-

- name: Install dependencies
run: mix deps.get

- name: Compile dependencies
run: mix deps.compile

- name: Set MIX_ENV to test
run: echo "MIX_ENV=test" >> $GITHUB_ENV

- name: Compile project
run: mix compile --warnings-as-errors

- name: Check formatting
run: mix format --check-formatted

- name: Run Credo
run: mix credo --strict

- name: Run tests
run: mix test
6 changes: 3 additions & 3 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

27 changes: 23 additions & 4 deletions lib/reencodarr/media/video_state_machine.ex
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ defmodule Reencodarr.Media.VideoStateMachine do

# Valid state transitions - only these transitions are allowed
@valid_transitions %{
needs_analysis: [:analyzed, :crf_searched, :failed],
analyzed: [:crf_searching, :crf_searched, :failed],
needs_analysis: [:analyzed, :crf_searched, :encoded, :failed],
analyzed: [:crf_searching, :crf_searched, :encoded, :failed],
# Can go back to analyzed if CRF search is cancelled
crf_searching: [:crf_searched, :failed, :analyzed],
# Can restart CRF search if needed
Expand Down Expand Up @@ -99,8 +99,19 @@ defmodule Reencodarr.Media.VideoStateMachine do
end

def transition_to_analyzed(%Video{} = video, attrs \\ %{}) do
# Don't add any extra validation flags - let the changeset validation handle requirements
transition(video, :analyzed, attrs)
# Check if video has low bitrate and HDR content, should be marked as encoded
if low_bitrate?(video) do
bitrate_mbps = video.bitrate / 1_000_000

Logger.debug(
"Video #{video.path} has low bitrate (#{:erlang.float_to_binary(bitrate_mbps, decimals: 1)} Mbps) and HDR, marking as encoded"
)
Comment thread
mjc marked this conversation as resolved.

transition(video, :encoded, attrs)
else
# Don't add any extra validation flags - let the changeset validation handle requirements
transition(video, :analyzed, attrs)
end
end

def transition_to_crf_searching(%Video{} = video, attrs \\ %{}) do
Expand Down Expand Up @@ -408,4 +419,12 @@ defmodule Reencodarr.Media.VideoStateMachine do
end

# Private helper functions

# Check if video has low bitrate (less than 5 Mbps = 5,000,000 bps) AND is HDR and should skip encoding
defp low_bitrate?(%Video{bitrate: bitrate, hdr: hdr})
when is_integer(bitrate) and bitrate > 0 and not is_nil(hdr) do
bitrate < 5_000_000
end

defp low_bitrate?(_video), do: false
end
Loading