Skip to content

Releases: deadfin-org/deadfin

v0.3.1

Choose a tag to compare

@github-actions github-actions released this 03 Nov 15:48
v0.3.1
dcee71c

Security

  • The toolchain is Go 1.26.10. It fixes GO-2026-6809 in crypto/x509,
    which the HTTPS server reaches through certificate verification.

Image

docker pull ghcr.io/deadfin-org/deadfin:v0.3.1
docker pull ghcr.io/deadfin-org/deadfin@sha256:9d80d78be2177073aa7906aa6535411112589588542e4c7848dd6f5895dffb2f

Platforms: linux/amd64, linux/arm64. See docs/alpha to install.

Verify

The image carries a build provenance attestation and an SPDX SBOM attestation for each architecture. The SBOMs are attached to this release.

gh attestation verify oci://ghcr.io/deadfin-org/deadfin@sha256:9d80d78be2177073aa7906aa6535411112589588542e4c7848dd6f5895dffb2f --repo deadfin-org/deadfin

v0.3.0

Choose a tag to compare

@github-actions github-actions released this 03 Nov 01:36
v0.3.0
9bc1f4e

v0.3.0 is the first public alpha of Deadfin.

Highlights

  • The image includes deadfin-web. Deadfin serves the bundled web client
    (v0.3.0-rc.4) at /web/ with no extra download. To use jellyfin-web
    instead, put its files in ./deadfin/web and mount that directory at
    /var/lib/deadfin/web; a <data root>/web with an index.html replaces
    the bundled client. An existing ./deadfin/web mount keeps working and
    keeps its own files: remove the mount to use the bundled deadfin-web.
  • Audio and subtitle choice carries to the next episode (D-36). When you
    pick a language or a subtitle track in one episode, the next episode of the
    same series starts with the matching tracks. Subtitles off also carries.
  • Anime search finds every title (D-48). Search matches the English,
    romaji, native and alias titles from AniList and AniDB, with a kana/romaji
    fold. "Shingeki" and "進撃" both find "Attack on Titan".
  • PostgreSQL support. SQLite stays the default. Set
    DEADFIN_DATABASE_URL (or --database-url) to a postgres:// URL to run
    on PostgreSQL. See docs/alpha/install.md.
  • Security fixes from the release-candidate review: sign-out revokes the
    token, video attachments are scoped to the user, the image downloader
    refuses special-purpose address ranges, and the toolchain is Go 1.26.9.

Added

  • CHANGELOG.md. Each GitHub Release body comes from its section here.
  • Release images carry a build provenance attestation and an SPDX SBOM for
    each architecture. The SBOMs are attached to the GitHub Release.
  • The :alpha image tag. It follows the newest release or release
    candidate. The :latest tag follows the newest release (no -rc.N), so
    v0.3.0 publishes it first.
  • Person pages show a biography, birth date, death date and birthplace from
    TMDb. Opening a person without metadata fetches it, and the "Refresh
    People" scheduled task fetches it for every person not yet refreshed
    (D-74). Cast and crew keep their TMDb person ID. This needs a TMDb API
    key (D-11).
  • The integrations guide: connect Seerr, Sonarr, Radarr and Bazarr beside
    Jellyfin and after the cutover, with a script that moves Seerr users to
    their Deadfin IDs. See
    docs/alpha/integrations.md.

Changed

  • The startup log names the web client in use: its directory, the source
    (data root or bundled) and the version from its build.json.
  • The quick start and the install guide put TMDb API key setup first.
  • DEADFIN_DATA_DIR sets the data root. JELLYFIN_DATA_DIR stays as the
    fallback. The image sets its default, /var/lib/deadfin, in JELLYFIN_DATA_DIR,
    so a deployment that sets either variable overrides it. Deadfin
    logs a warning for each set JELLYFIN_CONFIG_DIR, JELLYFIN_CACHE_DIR,
    JELLYFIN_LOG_DIR or JELLYFIN_WEB_DIR.

Security

  • POST /Sessions/Capabilities and POST /Sessions/Capabilities/Full
    refuse another user's session ID from a non-administrator caller (D-67).
  • /web/ responses send Referrer-Policy: no-referrer and
    X-Content-Type-Options: nosniff. When the served client is deadfin-web,
    they also send a restrictive Content-Security-Policy with
    frame-ancestors 'none' (D-68).
  • The one-time setup cookie is Secure when a KnownProxies peer reports
    HTTPS in X-Forwarded-Proto. Behind a TLS-terminating proxy, list the
    proxy in KnownProxies before first start (D-53).

Fixed

  • A MusicBrainz timeout or rate-limit wait no longer fails the whole artist
    folder. When a remote metadata provider's own request deadline expires, the
    item keeps its stored metadata, the scan logs one remote metadata provider failed warning, and the folder stays ok. A cancelled scan still stops
    (D-107, #749; regression of #367).
  • A music album carries the artists of its songs, as upstream does:
    AlbumArtist, AlbumArtists, Artists and ArtistItems. The album
    artists of most songs come first. Before, no album had an album artist, so
    clients showed none on album tiles (#739). An album scanned before this
    change gets its artists on the next library scan (D-110). A locked album
    keeps its values.
  • Refresh Metadata saves provider IDs and images for every library root
    again. A cast member, studio, or genre whose name differs only in case from
    the stored one (Starz and STARZ) has the same item ID but a different
    path, and the refresh failed the whole folder with path mismatch; for a
    library root, nothing was saved. The refresh now keeps the stored person,
    studio, or genre path, as upstream does. A stale row of a removed
    case-variant folder no longer fails its surviving sibling with
    parent mismatch: the refresh moves it under the scanned folder, as an
    ordinary scan does (#748).
  • A music track whose file carries an embedded cover (an attached picture,
    as FLAC and MP3 files often do) gets that cover as its Primary image, and
    an album without a cover file takes the Primary image of its first track.
    Before, the embedded cover was never extracted, so an album without a
    folder.jpg had no image (#784, D-108).
  • A library scan gives a music track that has no Primary image its embedded
    cover, also when the file did not change. Before, a track scanned before
    #784 got its cover only on a full image refresh, so the album stayed
    without a cover after an upgrade (#804, D-117).
  • A refresh with ReplaceAllImages keeps a stored image that no provider
    replaces, as upstream does. Before, it removed every stored image, so an
    album with a remote cover and no other source lost its cover (#804).
  • GET /Items/{itemId}/RemoteImages lists TheAudioDB for a music album
    (Primary, Disc) by its MusicBrainz release-group ID, and for a music
    artist (Primary, Logo, Banner, Backdrop) by its MusicBrainz artist ID, as
    upstream AudioDbAlbumImageProvider and AudioDbArtistImageProvider do.
    Before, no remote image provider supported music items, so a cover could
    not be picked in the image editor. TheAudioDB needs AUDIODB_API_KEY
    (D-11) (#807).
  • A library scan follows symbolic links, as upstream does. A linked media
    file or a linked directory, also one outside the library root, enters the
    library under the link path; before, the scan left every link out. A
    dangling link is skipped with a warning. A directory link to the directory
    that holds it or to one of its ancestors is skipped with a warning (D-86).
    A file link's snapshot now carries the facts of its target, so playback and
    probing check the target file.
  • Every artist named in an ARTIST or album_artist tag gets a MusicArtist
    item after a library scan, as upstream ArtistsValidator does. Before,
    only artist folders made artists, so /Artists and /Artists/AlbumArtists
    left out featured artists and album artists without a folder (#739). An
    artist folder serves its own name. An artist that no track names any more
    is deleted on the next scan, unless it is locked.
  • The library scan logs a folder failure when the folder fails. Before, the
    scanner folder lines came only after the whole scan ended, so a scan that
    stalled logged no failure at all (#702).
  • A library scan keeps a folder that holds two names that differ only in
    case, such as Live and live on a case-sensitive NFS or ZFS share. Both
    names gave the same item ID, and the whole folder failed on every scan: an
    artist's discography, a season, or at the library root the whole library
    stayed missing. The scan now keeps the first name in ordinal order and logs
    the other as skipped (D-85). A directory entry whose file status cannot be
    read is skipped with a warning; before, one such entry failed the listing
    of its whole directory (#702).
  • A multi-disc album is one album, as in Jellyfin. An album folder whose
    tracks are in disc folders (CD 01, Disc 1, Digital Media 01, and the
    other Jellyfin disc names) is the MusicAlbum, its parent folder is the
    artist, and the disc folders are plain folders. The album lists the tracks
    of every disc, its track count includes every disc, and each track shows
    the album. Before, each disc folder was an album named after the folder,
    with no album artist. A library scan replaces those albums (#703).
  • The library scan ignores Jellyfin trickplay directories, as Jellyfin does.
    With "save trickplay with media" on, Jellyfin writes a
    <video>.trickplay/ directory next to each video. Deadfin indexed these
    directories and their tile directories as Folder items that showed in
    browse and search. The next scan removes Folder items that an earlier scan
    made for them (#704).
  • The library scan ignores Synology and QNAP system directories, as
    Jellyfin does: @eaDir, eaDir, #recycle, @Recycle, .@__thumb,
    $RECYCLE.BIN, System Volume Information and .grab. On a Synology
    share, Deadfin indexed the @eaDir thumbnail directories as items, and an
    @eaDir at the root of a Shows library became a series named "@eadir".
  • HLS copies a Dolby Vision profile 7 (dual-layer) HEVC stream as HDR10 for a
    client that lists HDR10 but not DOVIWithEL in its range types. The copy
    removes the RPU and the enhancement layer with hevc_metadata=remove_dovi
    (or dovi_rpu=strip) and the master playlist offers an hvc1 variant with
    VIDEO-RANGE=PQ, as upstream does. Before, such a client got a 4K SDR
    H.264 tone-mapped transcode. Startup probes which removal filters ffmpeg
    has. The same port strips HDR10+ from a profile 8.1 HDR10+ copy for a
    Dolby Vision client, and Dolby Vision from an invalid configuration (#586,
    D-84).
  • import-jellyfin reads a Jellyfin database in WAL mode from the read-only
    /import mount that the import guide uses. The importer opens the stopped
    copy immutable, so SQLite creates no jellyfin.db-shm next to it. A
    non-empty jellyfin.db-wal stops the import with a message to stop
    Jellyfin and c...
Read more

v0.3.0-rc.20

v0.3.0-rc.20 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 02 Nov 05:39
v0.3.0-rc.20
83b1446

v0.3.0 is the first public alpha of Deadfin.

Highlights

  • The image includes deadfin-web. Deadfin serves the bundled web client
    (v0.3.0-rc.4) at /web/ with no extra download. To use jellyfin-web
    instead, put its files in ./deadfin/web and mount that directory at
    /var/lib/deadfin/web; a <data root>/web with an index.html replaces
    the bundled client. An existing ./deadfin/web mount keeps working and
    keeps its own files: remove the mount to use the bundled deadfin-web.
  • Audio and subtitle choice carries to the next episode (D-36). When you
    pick a language or a subtitle track in one episode, the next episode of the
    same series starts with the matching tracks. Subtitles off also carries.
  • Anime search finds every title (D-48). Search matches the English,
    romaji, native and alias titles from AniList and AniDB, with a kana/romaji
    fold. "Shingeki" and "進撃" both find "Attack on Titan".
  • PostgreSQL support. SQLite stays the default. Set
    DEADFIN_DATABASE_URL (or --database-url) to a postgres:// URL to run
    on PostgreSQL. See docs/alpha/install.md.
  • Security fixes from the release-candidate review: sign-out revokes the
    token, video attachments are scoped to the user, the image downloader
    refuses special-purpose address ranges, and the toolchain is Go 1.26.9.

Added

  • CHANGELOG.md. Each GitHub Release body comes from its section here.
  • Release images carry a build provenance attestation and an SPDX SBOM for
    each architecture. The SBOMs are attached to the GitHub Release.
  • The :alpha image tag. It follows the newest release or release
    candidate. The :latest tag follows the newest release (no -rc.N), so
    v0.3.0 publishes it first.
  • Person pages show a biography, birth date, death date and birthplace from
    TMDb. Opening a person without metadata fetches it, and the "Refresh
    People" scheduled task fetches it for every person not yet refreshed
    (D-74). Cast and crew keep their TMDb person ID. This needs a TMDb API
    key (D-11).
  • The integrations guide: connect Seerr, Sonarr, Radarr and Bazarr beside
    Jellyfin and after the cutover, with a script that moves Seerr users to
    their Deadfin IDs. See
    docs/alpha/integrations.md.

Changed

  • The startup log names the web client in use: its directory, the source
    (data root or bundled) and the version from its build.json.
  • The quick start and the install guide put TMDb API key setup first.
  • DEADFIN_DATA_DIR sets the data root. JELLYFIN_DATA_DIR stays as the
    fallback. The image sets its default, /var/lib/deadfin, in JELLYFIN_DATA_DIR,
    so a deployment that sets either variable overrides it. Deadfin
    logs a warning for each set JELLYFIN_CONFIG_DIR, JELLYFIN_CACHE_DIR,
    JELLYFIN_LOG_DIR or JELLYFIN_WEB_DIR.

Security

  • POST /Sessions/Capabilities and POST /Sessions/Capabilities/Full
    refuse another user's session ID from a non-administrator caller (D-67).
  • /web/ responses send Referrer-Policy: no-referrer and
    X-Content-Type-Options: nosniff. When the served client is deadfin-web,
    they also send a restrictive Content-Security-Policy with
    frame-ancestors 'none' (D-68).
  • The one-time setup cookie is Secure when a KnownProxies peer reports
    HTTPS in X-Forwarded-Proto. Behind a TLS-terminating proxy, list the
    proxy in KnownProxies before first start (D-53).

Fixed

  • A MusicBrainz timeout or rate-limit wait no longer fails the whole artist
    folder. When a remote metadata provider's own request deadline expires, the
    item keeps its stored metadata, the scan logs one remote metadata provider failed warning, and the folder stays ok. A cancelled scan still stops
    (D-107, #749; regression of #367).
  • A music album carries the artists of its songs, as upstream does:
    AlbumArtist, AlbumArtists, Artists and ArtistItems. The album
    artists of most songs come first. Before, no album had an album artist, so
    clients showed none on album tiles (#739). An album scanned before this
    change gets its artists on the next library scan (D-110). A locked album
    keeps its values.
  • Refresh Metadata saves provider IDs and images for every library root
    again. A cast member, studio, or genre whose name differs only in case from
    the stored one (Starz and STARZ) has the same item ID but a different
    path, and the refresh failed the whole folder with path mismatch; for a
    library root, nothing was saved. The refresh now keeps the stored person,
    studio, or genre path, as upstream does. A stale row of a removed
    case-variant folder no longer fails its surviving sibling with
    parent mismatch: the refresh moves it under the scanned folder, as an
    ordinary scan does (#748).
  • A music track whose file carries an embedded cover (an attached picture,
    as FLAC and MP3 files often do) gets that cover as its Primary image, and
    an album without a cover file takes the Primary image of its first track.
    Before, the embedded cover was never extracted, so an album without a
    folder.jpg had no image (#784, D-108).
  • A library scan gives a music track that has no Primary image its embedded
    cover, also when the file did not change. Before, a track scanned before
    #784 got its cover only on a full image refresh, so the album stayed
    without a cover after an upgrade (#804, D-117).
  • A refresh with ReplaceAllImages keeps a stored image that no provider
    replaces, as upstream does. Before, it removed every stored image, so an
    album with a remote cover and no other source lost its cover (#804).
  • GET /Items/{itemId}/RemoteImages lists TheAudioDB for a music album
    (Primary, Disc) by its MusicBrainz release-group ID, and for a music
    artist (Primary, Logo, Banner, Backdrop) by its MusicBrainz artist ID, as
    upstream AudioDbAlbumImageProvider and AudioDbArtistImageProvider do.
    Before, no remote image provider supported music items, so a cover could
    not be picked in the image editor. TheAudioDB needs AUDIODB_API_KEY
    (D-11) (#807).
  • A library scan follows symbolic links, as upstream does. A linked media
    file or a linked directory, also one outside the library root, enters the
    library under the link path; before, the scan left every link out. A
    dangling link is skipped with a warning. A directory link to the directory
    that holds it or to one of its ancestors is skipped with a warning (D-86).
    A file link's snapshot now carries the facts of its target, so playback and
    probing check the target file.
  • Every artist named in an ARTIST or album_artist tag gets a MusicArtist
    item after a library scan, as upstream ArtistsValidator does. Before,
    only artist folders made artists, so /Artists and /Artists/AlbumArtists
    left out featured artists and album artists without a folder (#739). An
    artist folder serves its own name. An artist that no track names any more
    is deleted on the next scan, unless it is locked.
  • The library scan logs a folder failure when the folder fails. Before, the
    scanner folder lines came only after the whole scan ended, so a scan that
    stalled logged no failure at all (#702).
  • A library scan keeps a folder that holds two names that differ only in
    case, such as Live and live on a case-sensitive NFS or ZFS share. Both
    names gave the same item ID, and the whole folder failed on every scan: an
    artist's discography, a season, or at the library root the whole library
    stayed missing. The scan now keeps the first name in ordinal order and logs
    the other as skipped (D-85). A directory entry whose file status cannot be
    read is skipped with a warning; before, one such entry failed the listing
    of its whole directory (#702).
  • A multi-disc album is one album, as in Jellyfin. An album folder whose
    tracks are in disc folders (CD 01, Disc 1, Digital Media 01, and the
    other Jellyfin disc names) is the MusicAlbum, its parent folder is the
    artist, and the disc folders are plain folders. The album lists the tracks
    of every disc, its track count includes every disc, and each track shows
    the album. Before, each disc folder was an album named after the folder,
    with no album artist. A library scan replaces those albums (#703).
  • The library scan ignores Jellyfin trickplay directories, as Jellyfin does.
    With "save trickplay with media" on, Jellyfin writes a
    <video>.trickplay/ directory next to each video. Deadfin indexed these
    directories and their tile directories as Folder items that showed in
    browse and search. The next scan removes Folder items that an earlier scan
    made for them (#704).
  • The library scan ignores Synology and QNAP system directories, as
    Jellyfin does: @eaDir, eaDir, #recycle, @Recycle, .@__thumb,
    $RECYCLE.BIN, System Volume Information and .grab. On a Synology
    share, Deadfin indexed the @eaDir thumbnail directories as items, and an
    @eaDir at the root of a Shows library became a series named "@eadir".
  • HLS copies a Dolby Vision profile 7 (dual-layer) HEVC stream as HDR10 for a
    client that lists HDR10 but not DOVIWithEL in its range types. The copy
    removes the RPU and the enhancement layer with hevc_metadata=remove_dovi
    (or dovi_rpu=strip) and the master playlist offers an hvc1 variant with
    VIDEO-RANGE=PQ, as upstream does. Before, such a client got a 4K SDR
    H.264 tone-mapped transcode. Startup probes which removal filters ffmpeg
    has. The same port strips HDR10+ from a profile 8.1 HDR10+ copy for a
    Dolby Vision client, and Dolby Vision from an invalid configuration (#586,
    D-84).
  • import-jellyfin reads a Jellyfin database in WAL mode from the read-only
    /import mount that the import guide uses. The importer opens the stopped
    copy immutable, so SQLite creates no jellyfin.db-shm next to it. A
    non-empty jellyfin.db-wal stops the import with a message to stop
    Jellyfin and c...
Read more

v0.3.0-rc.19

v0.3.0-rc.19 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 01 Nov 05:38
v0.3.0-rc.19
796d591

v0.3.0 is the first public alpha of Deadfin.

Highlights

  • The image includes deadfin-web. Deadfin serves the bundled web client
    (v0.3.0-rc.4) at /web/ with no extra download. To use jellyfin-web
    instead, put its files in ./deadfin/web and mount that directory at
    /var/lib/deadfin/web; a <data root>/web with an index.html replaces
    the bundled client. An existing ./deadfin/web mount keeps working and
    keeps its own files: remove the mount to use the bundled deadfin-web.
  • Audio and subtitle choice carries to the next episode (D-36). When you
    pick a language or a subtitle track in one episode, the next episode of the
    same series starts with the matching tracks. Subtitles off also carries.
  • Anime search finds every title (D-48). Search matches the English,
    romaji, native and alias titles from AniList and AniDB, with a kana/romaji
    fold. "Shingeki" and "進撃" both find "Attack on Titan".
  • PostgreSQL support. SQLite stays the default. Set
    DEADFIN_DATABASE_URL (or --database-url) to a postgres:// URL to run
    on PostgreSQL. See docs/alpha/install.md.
  • Security fixes from the release-candidate review: sign-out revokes the
    token, video attachments are scoped to the user, the image downloader
    refuses special-purpose address ranges, and the toolchain is Go 1.26.9.

Added

  • CHANGELOG.md. Each GitHub Release body comes from its section here.
  • Release images carry a build provenance attestation and an SPDX SBOM for
    each architecture. The SBOMs are attached to the GitHub Release.
  • The :alpha image tag. It follows the newest release or release
    candidate. The :latest tag follows the newest release (no -rc.N), so
    v0.3.0 publishes it first.
  • Person pages show a biography, birth date, death date and birthplace from
    TMDb. Opening a person without metadata fetches it, and the "Refresh
    People" scheduled task fetches it for every person not yet refreshed
    (D-74). Cast and crew keep their TMDb person ID. This needs a TMDb API
    key (D-11).
  • The integrations guide: connect Seerr, Sonarr, Radarr and Bazarr beside
    Jellyfin and after the cutover, with a script that moves Seerr users to
    their Deadfin IDs. See
    docs/alpha/integrations.md.

Changed

  • The startup log names the web client in use: its directory, the source
    (data root or bundled) and the version from its build.json.
  • The quick start and the install guide put TMDb API key setup first.
  • DEADFIN_DATA_DIR sets the data root. JELLYFIN_DATA_DIR stays as the
    fallback. The image sets its default, /var/lib/deadfin, in JELLYFIN_DATA_DIR,
    so a deployment that sets either variable overrides it. Deadfin
    logs a warning for each set JELLYFIN_CONFIG_DIR, JELLYFIN_CACHE_DIR,
    JELLYFIN_LOG_DIR or JELLYFIN_WEB_DIR.

Security

  • POST /Sessions/Capabilities and POST /Sessions/Capabilities/Full
    refuse another user's session ID from a non-administrator caller (D-67).
  • /web/ responses send Referrer-Policy: no-referrer and
    X-Content-Type-Options: nosniff. When the served client is deadfin-web,
    they also send a restrictive Content-Security-Policy with
    frame-ancestors 'none' (D-68).
  • The one-time setup cookie is Secure when a KnownProxies peer reports
    HTTPS in X-Forwarded-Proto. Behind a TLS-terminating proxy, list the
    proxy in KnownProxies before first start (D-53).

Fixed

  • A MusicBrainz timeout or rate-limit wait no longer fails the whole artist
    folder. When a remote metadata provider's own request deadline expires, the
    item keeps its stored metadata, the scan logs one remote metadata provider failed warning, and the folder stays ok. A cancelled scan still stops
    (D-107, #749; regression of #367).
  • A music album carries the artists of its songs, as upstream does:
    AlbumArtist, AlbumArtists, Artists and ArtistItems. The album
    artists of most songs come first. Before, no album had an album artist, so
    clients showed none on album tiles (#739). An album scanned before this
    change gets its artists on the next library scan (D-110). A locked album
    keeps its values.
  • Refresh Metadata saves provider IDs and images for every library root
    again. A cast member, studio, or genre whose name differs only in case from
    the stored one (Starz and STARZ) has the same item ID but a different
    path, and the refresh failed the whole folder with path mismatch; for a
    library root, nothing was saved. The refresh now keeps the stored person,
    studio, or genre path, as upstream does. A stale row of a removed
    case-variant folder no longer fails its surviving sibling with
    parent mismatch: the refresh moves it under the scanned folder, as an
    ordinary scan does (#748).
  • A music track whose file carries an embedded cover (an attached picture,
    as FLAC and MP3 files often do) gets that cover as its Primary image, and
    an album without a cover file takes the Primary image of its first track.
    Before, the embedded cover was never extracted, so an album without a
    folder.jpg had no image (#784, D-108).
  • A library scan follows symbolic links, as upstream does. A linked media
    file or a linked directory, also one outside the library root, enters the
    library under the link path; before, the scan left every link out. A
    dangling link is skipped with a warning. A directory link to the directory
    that holds it or to one of its ancestors is skipped with a warning (D-86).
    A file link's snapshot now carries the facts of its target, so playback and
    probing check the target file.
  • Every artist named in an ARTIST or album_artist tag gets a MusicArtist
    item after a library scan, as upstream ArtistsValidator does. Before,
    only artist folders made artists, so /Artists and /Artists/AlbumArtists
    left out featured artists and album artists without a folder (#739). An
    artist folder serves its own name. An artist that no track names any more
    is deleted on the next scan, unless it is locked.
  • The library scan logs a folder failure when the folder fails. Before, the
    scanner folder lines came only after the whole scan ended, so a scan that
    stalled logged no failure at all (#702).
  • A library scan keeps a folder that holds two names that differ only in
    case, such as Live and live on a case-sensitive NFS or ZFS share. Both
    names gave the same item ID, and the whole folder failed on every scan: an
    artist's discography, a season, or at the library root the whole library
    stayed missing. The scan now keeps the first name in ordinal order and logs
    the other as skipped (D-85). A directory entry whose file status cannot be
    read is skipped with a warning; before, one such entry failed the listing
    of its whole directory (#702).
  • A multi-disc album is one album, as in Jellyfin. An album folder whose
    tracks are in disc folders (CD 01, Disc 1, Digital Media 01, and the
    other Jellyfin disc names) is the MusicAlbum, its parent folder is the
    artist, and the disc folders are plain folders. The album lists the tracks
    of every disc, its track count includes every disc, and each track shows
    the album. Before, each disc folder was an album named after the folder,
    with no album artist. A library scan replaces those albums (#703).
  • The library scan ignores Jellyfin trickplay directories, as Jellyfin does.
    With "save trickplay with media" on, Jellyfin writes a
    <video>.trickplay/ directory next to each video. Deadfin indexed these
    directories and their tile directories as Folder items that showed in
    browse and search. The next scan removes Folder items that an earlier scan
    made for them (#704).
  • The library scan ignores Synology and QNAP system directories, as
    Jellyfin does: @eaDir, eaDir, #recycle, @Recycle, .@__thumb,
    $RECYCLE.BIN, System Volume Information and .grab. On a Synology
    share, Deadfin indexed the @eaDir thumbnail directories as items, and an
    @eaDir at the root of a Shows library became a series named "@eadir".
  • HLS copies a Dolby Vision profile 7 (dual-layer) HEVC stream as HDR10 for a
    client that lists HDR10 but not DOVIWithEL in its range types. The copy
    removes the RPU and the enhancement layer with hevc_metadata=remove_dovi
    (or dovi_rpu=strip) and the master playlist offers an hvc1 variant with
    VIDEO-RANGE=PQ, as upstream does. Before, such a client got a 4K SDR
    H.264 tone-mapped transcode. Startup probes which removal filters ffmpeg
    has. The same port strips HDR10+ from a profile 8.1 HDR10+ copy for a
    Dolby Vision client, and Dolby Vision from an invalid configuration (#586,
    D-84).
  • import-jellyfin reads a Jellyfin database in WAL mode from the read-only
    /import mount that the import guide uses. The importer opens the stopped
    copy immutable, so SQLite creates no jellyfin.db-shm next to it. A
    non-empty jellyfin.db-wal stops the import with a message to stop
    Jellyfin and copy again (#697).
  • HLS plays an audio track that starts late. A track whose first packet is
    more than 1 s into the file is encoded with leading silence instead of
    copied: AAC when the client accepts it, else AC3 or E-AC3. A copied late
    AC3 track gave an init segment without dac3 and first segments without
    audio, and AVPlayer failed the item at once. The Italian stereo track of a
    4K remux starts at 33.55 s (#681, D-82).
  • Embedded text subtitles of large files load. One ffmpeg pass extracts
    every embedded subtitle stream of a file into the subtitle cache, text
    streams included, as upstream does. The first request waits for the pass
    under SubtitleExtractionTimeoutMinutes; later requests read the cache. The
    forced track of a 4K remux returned 500 after 30 s (#676, D-52).
  • GET /UserItems/Resume and GET /Users/{userId}/Items/Resume honor
    parentId: they return only the in-progress items under the series,
    seaso...
Read more

v0.3.0-rc.18

v0.3.0-rc.18 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 01 Nov 05:38
v0.3.0-rc.18
293985e

v0.3.0 is the first public alpha of Deadfin.

Highlights

  • The image includes deadfin-web. Deadfin serves the bundled web client
    (v0.3.0-rc.4) at /web/ with no extra download. To use jellyfin-web
    instead, put its files in ./deadfin/web and mount that directory at
    /var/lib/deadfin/web; a <data root>/web with an index.html replaces
    the bundled client. An existing ./deadfin/web mount keeps working and
    keeps its own files: remove the mount to use the bundled deadfin-web.
  • Audio and subtitle choice carries to the next episode (D-36). When you
    pick a language or a subtitle track in one episode, the next episode of the
    same series starts with the matching tracks. Subtitles off also carries.
  • Anime search finds every title (D-48). Search matches the English,
    romaji, native and alias titles from AniList and AniDB, with a kana/romaji
    fold. "Shingeki" and "進撃" both find "Attack on Titan".
  • PostgreSQL support. SQLite stays the default. Set
    DEADFIN_DATABASE_URL (or --database-url) to a postgres:// URL to run
    on PostgreSQL. See docs/alpha/install.md.
  • Security fixes from the release-candidate review: sign-out revokes the
    token, video attachments are scoped to the user, the image downloader
    refuses special-purpose address ranges, and the toolchain is Go 1.26.9.

Added

  • CHANGELOG.md. Each GitHub Release body comes from its section here.
  • Release images carry a build provenance attestation and an SPDX SBOM for
    each architecture. The SBOMs are attached to the GitHub Release.
  • The :alpha image tag. It follows the newest release or release
    candidate. The :latest tag follows the newest release (no -rc.N), so
    v0.3.0 publishes it first.
  • Person pages show a biography, birth date, death date and birthplace from
    TMDb. Opening a person without metadata fetches it, and the "Refresh
    People" scheduled task fetches it for every person not yet refreshed
    (D-74). Cast and crew keep their TMDb person ID. This needs a TMDb API
    key (D-11).
  • The integrations guide: connect Seerr, Sonarr, Radarr and Bazarr beside
    Jellyfin and after the cutover, with a script that moves Seerr users to
    their Deadfin IDs. See
    docs/alpha/integrations.md.

Changed

  • The startup log names the web client in use: its directory, the source
    (data root or bundled) and the version from its build.json.
  • The quick start and the install guide put TMDb API key setup first.
  • DEADFIN_DATA_DIR sets the data root. JELLYFIN_DATA_DIR stays as the
    fallback. The image sets its default, /var/lib/deadfin, in JELLYFIN_DATA_DIR,
    so a deployment that sets either variable overrides it. Deadfin
    logs a warning for each set JELLYFIN_CONFIG_DIR, JELLYFIN_CACHE_DIR,
    JELLYFIN_LOG_DIR or JELLYFIN_WEB_DIR.

Security

  • POST /Sessions/Capabilities and POST /Sessions/Capabilities/Full
    refuse another user's session ID from a non-administrator caller (D-67).
  • /web/ responses send Referrer-Policy: no-referrer and
    X-Content-Type-Options: nosniff. When the served client is deadfin-web,
    they also send a restrictive Content-Security-Policy with
    frame-ancestors 'none' (D-68).
  • The one-time setup cookie is Secure when a KnownProxies peer reports
    HTTPS in X-Forwarded-Proto. Behind a TLS-terminating proxy, list the
    proxy in KnownProxies before first start (D-53).

Fixed

  • A MusicBrainz timeout or rate-limit wait no longer fails the whole artist
    folder. When a remote metadata provider's own request deadline expires, the
    item keeps its stored metadata, the scan logs one remote metadata provider failed warning, and the folder stays ok. A cancelled scan still stops
    (D-107, #749; regression of #367).
  • A music album carries the artists of its songs, as upstream does:
    AlbumArtist, AlbumArtists, Artists and ArtistItems. The album
    artists of most songs come first. Before, no album had an album artist, so
    clients showed none on album tiles (#739). An album scanned before this
    change gets its artists on the next library scan (D-110). A locked album
    keeps its values.
  • Refresh Metadata saves provider IDs and images for every library root
    again. A cast member, studio, or genre whose name differs only in case from
    the stored one (Starz and STARZ) has the same item ID but a different
    path, and the refresh failed the whole folder with path mismatch; for a
    library root, nothing was saved. The refresh now keeps the stored person,
    studio, or genre path, as upstream does. A stale row of a removed
    case-variant folder no longer fails its surviving sibling with
    parent mismatch: the refresh moves it under the scanned folder, as an
    ordinary scan does (#748).
  • A music track whose file carries an embedded cover (an attached picture,
    as FLAC and MP3 files often do) gets that cover as its Primary image, and
    an album without a cover file takes the Primary image of its first track.
    Before, the embedded cover was never extracted, so an album without a
    folder.jpg had no image (#784, D-108).
  • A library scan follows symbolic links, as upstream does. A linked media
    file or a linked directory, also one outside the library root, enters the
    library under the link path; before, the scan left every link out. A
    dangling link is skipped with a warning. A directory link to the directory
    that holds it or to one of its ancestors is skipped with a warning (D-86).
    A file link's snapshot now carries the facts of its target, so playback and
    probing check the target file.
  • Every artist named in an ARTIST or album_artist tag gets a MusicArtist
    item after a library scan, as upstream ArtistsValidator does. Before,
    only artist folders made artists, so /Artists and /Artists/AlbumArtists
    left out featured artists and album artists without a folder (#739). An
    artist folder serves its own name. An artist that no track names any more
    is deleted on the next scan, unless it is locked.
  • The library scan logs a folder failure when the folder fails. Before, the
    scanner folder lines came only after the whole scan ended, so a scan that
    stalled logged no failure at all (#702).
  • A library scan keeps a folder that holds two names that differ only in
    case, such as Live and live on a case-sensitive NFS or ZFS share. Both
    names gave the same item ID, and the whole folder failed on every scan: an
    artist's discography, a season, or at the library root the whole library
    stayed missing. The scan now keeps the first name in ordinal order and logs
    the other as skipped (D-85). A directory entry whose file status cannot be
    read is skipped with a warning; before, one such entry failed the listing
    of its whole directory (#702).
  • A multi-disc album is one album, as in Jellyfin. An album folder whose
    tracks are in disc folders (CD 01, Disc 1, Digital Media 01, and the
    other Jellyfin disc names) is the MusicAlbum, its parent folder is the
    artist, and the disc folders are plain folders. The album lists the tracks
    of every disc, its track count includes every disc, and each track shows
    the album. Before, each disc folder was an album named after the folder,
    with no album artist. A library scan replaces those albums (#703).
  • The library scan ignores Jellyfin trickplay directories, as Jellyfin does.
    With "save trickplay with media" on, Jellyfin writes a
    <video>.trickplay/ directory next to each video. Deadfin indexed these
    directories and their tile directories as Folder items that showed in
    browse and search. The next scan removes Folder items that an earlier scan
    made for them (#704).
  • The library scan ignores Synology and QNAP system directories, as
    Jellyfin does: @eaDir, eaDir, #recycle, @Recycle, .@__thumb,
    $RECYCLE.BIN, System Volume Information and .grab. On a Synology
    share, Deadfin indexed the @eaDir thumbnail directories as items, and an
    @eaDir at the root of a Shows library became a series named "@eadir".
  • HLS copies a Dolby Vision profile 7 (dual-layer) HEVC stream as HDR10 for a
    client that lists HDR10 but not DOVIWithEL in its range types. The copy
    removes the RPU and the enhancement layer with hevc_metadata=remove_dovi
    (or dovi_rpu=strip) and the master playlist offers an hvc1 variant with
    VIDEO-RANGE=PQ, as upstream does. Before, such a client got a 4K SDR
    H.264 tone-mapped transcode. Startup probes which removal filters ffmpeg
    has. The same port strips HDR10+ from a profile 8.1 HDR10+ copy for a
    Dolby Vision client, and Dolby Vision from an invalid configuration (#586,
    D-84).
  • import-jellyfin reads a Jellyfin database in WAL mode from the read-only
    /import mount that the import guide uses. The importer opens the stopped
    copy immutable, so SQLite creates no jellyfin.db-shm next to it. A
    non-empty jellyfin.db-wal stops the import with a message to stop
    Jellyfin and copy again (#697).
  • HLS plays an audio track that starts late. A track whose first packet is
    more than 1 s into the file is encoded with leading silence instead of
    copied: AAC when the client accepts it, else AC3 or E-AC3. A copied late
    AC3 track gave an init segment without dac3 and first segments without
    audio, and AVPlayer failed the item at once. The Italian stereo track of a
    4K remux starts at 33.55 s (#681, D-82).
  • Embedded text subtitles of large files load. One ffmpeg pass extracts
    every embedded subtitle stream of a file into the subtitle cache, text
    streams included, as upstream does. The first request waits for the pass
    under SubtitleExtractionTimeoutMinutes; later requests read the cache. The
    forced track of a 4K remux returned 500 after 30 s (#676, D-52).
  • GET /UserItems/Resume and GET /Users/{userId}/Items/Resume honor
    parentId: they return only the in-progress items under the series,
    seaso...
Read more

v0.3.0-rc.17

v0.3.0-rc.17 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 24 Oct 16:33
v0.3.0-rc.17
62a08e0

v0.3.0 is the first public alpha of Deadfin.

Highlights

  • The image includes deadfin-web. Deadfin serves the bundled web client
    (v0.3.0-rc.4) at /web/ with no extra download. To use jellyfin-web
    instead, put its files in ./deadfin/web and mount that directory at
    /var/lib/deadfin/web; a <data root>/web with an index.html replaces
    the bundled client. An existing ./deadfin/web mount keeps working and
    keeps its own files: remove the mount to use the bundled deadfin-web.
  • Audio and subtitle choice carries to the next episode (D-36). When you
    pick a language or a subtitle track in one episode, the next episode of the
    same series starts with the matching tracks. Subtitles off also carries.
  • Anime search finds every title (D-48). Search matches the English,
    romaji, native and alias titles from AniList and AniDB, with a kana/romaji
    fold. "Shingeki" and "進撃" both find "Attack on Titan".
  • PostgreSQL support. SQLite stays the default. Set
    DEADFIN_DATABASE_URL (or --database-url) to a postgres:// URL to run
    on PostgreSQL. See docs/alpha/install.md.
  • Security fixes from the release-candidate review: sign-out revokes the
    token, video attachments are scoped to the user, the image downloader
    refuses special-purpose address ranges, and the toolchain is Go 1.26.9.

Added

  • CHANGELOG.md. Each GitHub Release body comes from its section here.
  • Release images carry a build provenance attestation and an SPDX SBOM for
    each architecture. The SBOMs are attached to the GitHub Release.
  • The :alpha image tag. It follows the newest release or release
    candidate. The :latest tag follows the newest release (no -rc.N), so
    v0.3.0 publishes it first.
  • Person pages show a biography, birth date, death date and birthplace from
    TMDb. Opening a person without metadata fetches it, and the "Refresh
    People" scheduled task fetches it for every person not yet refreshed
    (D-74). Cast and crew keep their TMDb person ID. This needs a TMDb API
    key (D-11).
  • The integrations guide: connect Seerr, Sonarr, Radarr and Bazarr beside
    Jellyfin and after the cutover, with a script that moves Seerr users to
    their Deadfin IDs. See
    docs/alpha/integrations.md.

Changed

  • The startup log names the web client in use: its directory, the source
    (data root or bundled) and the version from its build.json.
  • The quick start and the install guide put TMDb API key setup first.
  • DEADFIN_DATA_DIR sets the data root. JELLYFIN_DATA_DIR stays as the
    fallback. The image sets its default, /var/lib/deadfin, in JELLYFIN_DATA_DIR,
    so a deployment that sets either variable overrides it. Deadfin
    logs a warning for each set JELLYFIN_CONFIG_DIR, JELLYFIN_CACHE_DIR,
    JELLYFIN_LOG_DIR or JELLYFIN_WEB_DIR.

Security

  • POST /Sessions/Capabilities and POST /Sessions/Capabilities/Full
    refuse another user's session ID from a non-administrator caller (D-67).
  • /web/ responses send Referrer-Policy: no-referrer and
    X-Content-Type-Options: nosniff. When the served client is deadfin-web,
    they also send a restrictive Content-Security-Policy with
    frame-ancestors 'none' (D-68).
  • The one-time setup cookie is Secure when a KnownProxies peer reports
    HTTPS in X-Forwarded-Proto. Behind a TLS-terminating proxy, list the
    proxy in KnownProxies before first start (D-53).

Fixed

  • A library scan follows symbolic links, as upstream does. A linked media
    file or a linked directory, also one outside the library root, enters the
    library under the link path; before, the scan left every link out. A
    dangling link is skipped with a warning. A directory link to the directory
    that holds it or to one of its ancestors is skipped with a warning (D-86).
    A file link's snapshot now carries the facts of its target, so playback and
    probing check the target file.
  • The library scan logs a folder failure when the folder fails. Before, the
    scanner folder lines came only after the whole scan ended, so a scan that
    stalled logged no failure at all (#702).
  • A library scan keeps a folder that holds two names that differ only in
    case, such as Live and live on a case-sensitive NFS or ZFS share. Both
    names gave the same item ID, and the whole folder failed on every scan: an
    artist's discography, a season, or at the library root the whole library
    stayed missing. The scan now keeps the first name in ordinal order and logs
    the other as skipped (D-85). A directory entry whose file status cannot be
    read is skipped with a warning; before, one such entry failed the listing
    of its whole directory (#702).
  • A multi-disc album is one album, as in Jellyfin. An album folder whose
    tracks are in disc folders (CD 01, Disc 1, Digital Media 01, and the
    other Jellyfin disc names) is the MusicAlbum, its parent folder is the
    artist, and the disc folders are plain folders. The album lists the tracks
    of every disc, its track count includes every disc, and each track shows
    the album. Before, each disc folder was an album named after the folder,
    with no album artist. A library scan replaces those albums (#703).
  • The library scan ignores Jellyfin trickplay directories, as Jellyfin does.
    With "save trickplay with media" on, Jellyfin writes a
    <video>.trickplay/ directory next to each video. Deadfin indexed these
    directories and their tile directories as Folder items that showed in
    browse and search. The next scan removes Folder items that an earlier scan
    made for them (#704).
  • HLS copies a Dolby Vision profile 7 (dual-layer) HEVC stream as HDR10 for a
    client that lists HDR10 but not DOVIWithEL in its range types. The copy
    removes the RPU and the enhancement layer with hevc_metadata=remove_dovi
    (or dovi_rpu=strip) and the master playlist offers an hvc1 variant with
    VIDEO-RANGE=PQ, as upstream does. Before, such a client got a 4K SDR
    H.264 tone-mapped transcode. Startup probes which removal filters ffmpeg
    has. The same port strips HDR10+ from a profile 8.1 HDR10+ copy for a
    Dolby Vision client, and Dolby Vision from an invalid configuration (#586,
    D-84).
  • import-jellyfin reads a Jellyfin database in WAL mode from the read-only
    /import mount that the import guide uses. The importer opens the stopped
    copy immutable, so SQLite creates no jellyfin.db-shm next to it. A
    non-empty jellyfin.db-wal stops the import with a message to stop
    Jellyfin and copy again (#697).
  • HLS plays an audio track that starts late. A track whose first packet is
    more than 1 s into the file is encoded with leading silence instead of
    copied: AAC when the client accepts it, else AC3 or E-AC3. A copied late
    AC3 track gave an init segment without dac3 and first segments without
    audio, and AVPlayer failed the item at once. The Italian stereo track of a
    4K remux starts at 33.55 s (#681, D-82).
  • Embedded text subtitles of large files load. One ffmpeg pass extracts
    every embedded subtitle stream of a file into the subtitle cache, text
    streams included, as upstream does. The first request waits for the pass
    under SubtitleExtractionTimeoutMinutes; later requests read the cache. The
    forced track of a 4K remux returned 500 after 30 s (#676, D-52).
  • GET /UserItems/Resume and GET /Users/{userId}/Items/Resume honor
    parentId: they return only the in-progress items under the series,
    season, folder, library, collection, or playlist. Before, they returned the
    whole resume list, so the series Play button in Swiftfin played an
    unrelated movie. excludeActiveSessions now drops the items the user is
    playing, and the Latest exclusions apply only to the unscoped list, as
    upstream does (#674).
  • Sessions report the real play method. A report with no PlayMethod is
    Transcode while a transcoding job runs for its PlaySessionId, else
    DirectPlay, as upstream does. /Sessions carries TranscodingInfo for a
    running HLS job, so an HLS remux no longer shows as direct play (#635).
  • GET /Library/MediaFolders returns the library roots, as upstream does:
    the enabled collection folders and the hidden playlists folder, ordered by
    sort name, with the isHidden filter, for administrators only. Seerr and
    other Jellyfin tools that list libraries this way work without a fallback.
    The playlists folder projects as ManualPlaylistsFolder with
    CollectionType playlists (#596).
  • Comma-delimited enum query parameters drop unknown values, as upstream
    does. Infuse home rows (/Items/Latest with an Emby field) load again.
  • GET /MediaSegments/{itemId} returns an empty QueryResult for a known
    item (Infuse called it on every play).
  • HLS stream copy of Dolby Vision profile 7 (DOVIWithEL) is tagged hvc1,
    so the init segment matches the hvc1 master playlist and AVPlayer can
    decode the HDR10 base layer (D-65).
  • The H.264 level in the HLS master playlist matches the level the encoder
    writes (D-66).
  • The HLS throttler and the transcode cache limits pause ffmpeg again.
    jellyfin-ffmpeg 8 does not pause on the old key, so a fast remux kept writing
    segments far ahead of playback.
  • A user with access to only some libraries can open a person, genre or
    studio by its ID, as upstream does. Cast portraits returned 404 for these
    users. Lists keep the library restriction.

Image

docker pull ghcr.io/deadfin-org/deadfin:v0.3.0-rc.17
docker pull ghcr.io/deadfin-org/deadfin@sha256:501bf3b5c0ec259fb1006aa74415dd0891b18dbb5d2eeec3ac0a97c50112d016

Platforms: linux/amd64, linux/arm64. See docs/alpha to install.

Verify

The image carries a build provenance attestation and an SPDX SBOM attestation for each architecture. The SBOMs are attached to this release.

gh attestation verify oci://ghcr.io/deadfin-org/deadfin@sha256...
Read more

v0.3.0-rc.16

v0.3.0-rc.16 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 21 Oct 05:42
v0.3.0-rc.16
839adc2

v0.3.0 is the first public alpha of Deadfin.

Highlights

  • The image includes deadfin-web. Deadfin serves the bundled web client
    (v0.3.0-rc.4) at /web/ with no extra download. To use jellyfin-web
    instead, put its files in ./deadfin/web and mount that directory at
    /var/lib/deadfin/web; a <data root>/web with an index.html replaces
    the bundled client. An existing ./deadfin/web mount keeps working and
    keeps its own files: remove the mount to use the bundled deadfin-web.
  • Audio and subtitle choice carries to the next episode (D-36). When you
    pick a language or a subtitle track in one episode, the next episode of the
    same series starts with the matching tracks. Subtitles off also carries.
  • Anime search finds every title (D-48). Search matches the English,
    romaji, native and alias titles from AniList and AniDB, with a kana/romaji
    fold. "Shingeki" and "進撃" both find "Attack on Titan".
  • PostgreSQL support. SQLite stays the default. Set
    DEADFIN_DATABASE_URL (or --database-url) to a postgres:// URL to run
    on PostgreSQL. See docs/alpha/install.md.
  • Security fixes from the release-candidate review: sign-out revokes the
    token, video attachments are scoped to the user, the image downloader
    refuses special-purpose address ranges, and the toolchain is Go 1.26.9.

Added

  • CHANGELOG.md. Each GitHub Release body comes from its section here.
  • Release images carry a build provenance attestation and an SPDX SBOM for
    each architecture. The SBOMs are attached to the GitHub Release.
  • The :alpha image tag. It follows the newest release or release
    candidate. The :latest tag follows the newest release (no -rc.N), so
    v0.3.0 publishes it first.
  • Person pages show a biography, birth date, death date and birthplace from
    TMDb. Opening a person without metadata fetches it, and the "Refresh
    People" scheduled task fetches it for every person not yet refreshed
    (D-74). Cast and crew keep their TMDb person ID. This needs a TMDb API
    key (D-11).
  • The integrations guide: connect Seerr, Sonarr, Radarr and Bazarr beside
    Jellyfin and after the cutover, with a script that moves Seerr users to
    their Deadfin IDs. See
    docs/alpha/integrations.md.

Changed

  • The startup log names the web client in use: its directory, the source
    (data root or bundled) and the version from its build.json.
  • The quick start and the install guide put TMDb API key setup first.
  • DEADFIN_DATA_DIR sets the data root. JELLYFIN_DATA_DIR stays as the
    fallback. The image sets its default, /var/lib/deadfin, in JELLYFIN_DATA_DIR,
    so a deployment that sets either variable overrides it. Deadfin
    logs a warning for each set JELLYFIN_CONFIG_DIR, JELLYFIN_CACHE_DIR,
    JELLYFIN_LOG_DIR or JELLYFIN_WEB_DIR.

Security

  • POST /Sessions/Capabilities and POST /Sessions/Capabilities/Full
    refuse another user's session ID from a non-administrator caller (D-67).
  • /web/ responses send Referrer-Policy: no-referrer and
    X-Content-Type-Options: nosniff. When the served client is deadfin-web,
    they also send a restrictive Content-Security-Policy with
    frame-ancestors 'none' (D-68).
  • The one-time setup cookie is Secure when a KnownProxies peer reports
    HTTPS in X-Forwarded-Proto. Behind a TLS-terminating proxy, list the
    proxy in KnownProxies before first start (D-53).

Fixed

  • A library scan follows symbolic links, as upstream does. A linked media
    file or a linked directory, also one outside the library root, enters the
    library under the link path; before, the scan left every link out. A
    dangling link is skipped with a warning. A directory link to the directory
    that holds it or to one of its ancestors is skipped with a warning (D-86).
    A file link's snapshot now carries the facts of its target, so playback and
    probing check the target file.
  • The library scan logs a folder failure when the folder fails. Before, the
    scanner folder lines came only after the whole scan ended, so a scan that
    stalled logged no failure at all (#702).
  • A library scan keeps a folder that holds two names that differ only in
    case, such as Live and live on a case-sensitive NFS or ZFS share. Both
    names gave the same item ID, and the whole folder failed on every scan: an
    artist's discography, a season, or at the library root the whole library
    stayed missing. The scan now keeps the first name in ordinal order and logs
    the other as skipped (D-85). A directory entry whose file status cannot be
    read is skipped with a warning; before, one such entry failed the listing
    of its whole directory (#702).
  • A multi-disc album is one album, as in Jellyfin. An album folder whose
    tracks are in disc folders (CD 01, Disc 1, Digital Media 01, and the
    other Jellyfin disc names) is the MusicAlbum, its parent folder is the
    artist, and the disc folders are plain folders. The album lists the tracks
    of every disc, its track count includes every disc, and each track shows
    the album. Before, each disc folder was an album named after the folder,
    with no album artist. A library scan replaces those albums (#703).
  • The library scan ignores Jellyfin trickplay directories, as Jellyfin does.
    With "save trickplay with media" on, Jellyfin writes a
    <video>.trickplay/ directory next to each video. Deadfin indexed these
    directories and their tile directories as Folder items that showed in
    browse and search. The next scan removes Folder items that an earlier scan
    made for them (#704).
  • HLS copies a Dolby Vision profile 7 (dual-layer) HEVC stream as HDR10 for a
    client that lists HDR10 but not DOVIWithEL in its range types. The copy
    removes the RPU and the enhancement layer with hevc_metadata=remove_dovi
    (or dovi_rpu=strip) and the master playlist offers an hvc1 variant with
    VIDEO-RANGE=PQ, as upstream does. Before, such a client got a 4K SDR
    H.264 tone-mapped transcode. Startup probes which removal filters ffmpeg
    has. The same port strips HDR10+ from a profile 8.1 HDR10+ copy for a
    Dolby Vision client, and Dolby Vision from an invalid configuration (#586,
    D-84).
  • import-jellyfin reads a Jellyfin database in WAL mode from the read-only
    /import mount that the import guide uses. The importer opens the stopped
    copy immutable, so SQLite creates no jellyfin.db-shm next to it. A
    non-empty jellyfin.db-wal stops the import with a message to stop
    Jellyfin and copy again (#697).
  • HLS plays an audio track that starts late. A track whose first packet is
    more than 1 s into the file is encoded with leading silence instead of
    copied: AAC when the client accepts it, else AC3 or E-AC3. A copied late
    AC3 track gave an init segment without dac3 and first segments without
    audio, and AVPlayer failed the item at once. The Italian stereo track of a
    4K remux starts at 33.55 s (#681, D-82).
  • Embedded text subtitles of large files load. One ffmpeg pass extracts
    every embedded subtitle stream of a file into the subtitle cache, text
    streams included, as upstream does. The first request waits for the pass
    under SubtitleExtractionTimeoutMinutes; later requests read the cache. The
    forced track of a 4K remux returned 500 after 30 s (#676, D-52).
  • GET /UserItems/Resume and GET /Users/{userId}/Items/Resume honor
    parentId: they return only the in-progress items under the series,
    season, folder, library, collection, or playlist. Before, they returned the
    whole resume list, so the series Play button in Swiftfin played an
    unrelated movie. excludeActiveSessions now drops the items the user is
    playing, and the Latest exclusions apply only to the unscoped list, as
    upstream does (#674).
  • Sessions report the real play method. A report with no PlayMethod is
    Transcode while a transcoding job runs for its PlaySessionId, else
    DirectPlay, as upstream does. /Sessions carries TranscodingInfo for a
    running HLS job, so an HLS remux no longer shows as direct play (#635).
  • GET /Library/MediaFolders returns the library roots, as upstream does:
    the enabled collection folders and the hidden playlists folder, ordered by
    sort name, with the isHidden filter, for administrators only. Seerr and
    other Jellyfin tools that list libraries this way work without a fallback.
    The playlists folder projects as ManualPlaylistsFolder with
    CollectionType playlists (#596).
  • Comma-delimited enum query parameters drop unknown values, as upstream
    does. Infuse home rows (/Items/Latest with an Emby field) load again.
  • GET /MediaSegments/{itemId} returns an empty QueryResult for a known
    item (Infuse called it on every play).
  • HLS stream copy of Dolby Vision profile 7 (DOVIWithEL) is tagged hvc1,
    so the init segment matches the hvc1 master playlist and AVPlayer can
    decode the HDR10 base layer (D-65).
  • The H.264 level in the HLS master playlist matches the level the encoder
    writes (D-66).
  • The HLS throttler and the transcode cache limits pause ffmpeg again.
    jellyfin-ffmpeg 8 does not pause on the old key, so a fast remux kept writing
    segments far ahead of playback.
  • A user with access to only some libraries can open a person, genre or
    studio by its ID, as upstream does. Cast portraits returned 404 for these
    users. Lists keep the library restriction.

Image

docker pull ghcr.io/deadfin-org/deadfin:v0.3.0-rc.16
docker pull ghcr.io/deadfin-org/deadfin@sha256:e19e2c84a4fa2221ea4c4cda80e9e3d2eb216f24709941ea3dcb9b9024413c37

Platforms: linux/amd64, linux/arm64. See docs/alpha to install.

Verify

The image carries a build provenance attestation and an SPDX SBOM attestation for each architecture. The SBOMs are attached to this release.

gh attestation verify oci://ghcr.io/deadfin-org/deadfin@sha256...
Read more

v0.3.0-rc.15

v0.3.0-rc.15 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 19 Oct 04:44
v0.3.0-rc.15
2195696

v0.3.0 is the first public alpha of Deadfin.

Highlights

  • The image includes deadfin-web. Deadfin serves the bundled web client
    (v0.3.0-rc.4) at /web/ with no extra download. To use jellyfin-web
    instead, put its files in ./deadfin/web and mount that directory at
    /var/lib/deadfin/web; a <data root>/web with an index.html replaces
    the bundled client. An existing ./deadfin/web mount keeps working and
    keeps its own files: remove the mount to use the bundled deadfin-web.
  • Audio and subtitle choice carries to the next episode (D-36). When you
    pick a language or a subtitle track in one episode, the next episode of the
    same series starts with the matching tracks. Subtitles off also carries.
  • Anime search finds every title (D-48). Search matches the English,
    romaji, native and alias titles from AniList and AniDB, with a kana/romaji
    fold. "Shingeki" and "進撃" both find "Attack on Titan".
  • PostgreSQL support. SQLite stays the default. Set
    DEADFIN_DATABASE_URL (or --database-url) to a postgres:// URL to run
    on PostgreSQL. See docs/alpha/install.md.
  • Security fixes from the release-candidate review: sign-out revokes the
    token, video attachments are scoped to the user, the image downloader
    refuses special-purpose address ranges, and the toolchain is Go 1.26.9.

Added

  • CHANGELOG.md. Each GitHub Release body comes from its section here.
  • Release images carry a build provenance attestation and an SPDX SBOM for
    each architecture. The SBOMs are attached to the GitHub Release.
  • The :alpha image tag. It follows the newest release or release
    candidate. The :latest tag follows the newest release (no -rc.N), so
    v0.3.0 publishes it first.
  • Person pages show a biography, birth date, death date and birthplace from
    TMDb. Opening a person without metadata fetches it, and the "Refresh
    People" scheduled task fetches it for every person not yet refreshed
    (D-74). Cast and crew keep their TMDb person ID. This needs a TMDb API
    key (D-11).
  • The integrations guide: connect Seerr, Sonarr, Radarr and Bazarr beside
    Jellyfin and after the cutover, with a script that moves Seerr users to
    their Deadfin IDs. See
    docs/alpha/integrations.md.

Changed

  • The startup log names the web client in use: its directory, the source
    (data root or bundled) and the version from its build.json.
  • The quick start and the install guide put TMDb API key setup first.
  • DEADFIN_DATA_DIR sets the data root. JELLYFIN_DATA_DIR stays as the
    fallback. The image sets its default, /var/lib/deadfin, in JELLYFIN_DATA_DIR,
    so a deployment that sets either variable overrides it. Deadfin
    logs a warning for each set JELLYFIN_CONFIG_DIR, JELLYFIN_CACHE_DIR,
    JELLYFIN_LOG_DIR or JELLYFIN_WEB_DIR.

Security

  • POST /Sessions/Capabilities and POST /Sessions/Capabilities/Full
    refuse another user's session ID from a non-administrator caller (D-67).
  • /web/ responses send Referrer-Policy: no-referrer and
    X-Content-Type-Options: nosniff. When the served client is deadfin-web,
    they also send a restrictive Content-Security-Policy with
    frame-ancestors 'none' (D-68).
  • The one-time setup cookie is Secure when a KnownProxies peer reports
    HTTPS in X-Forwarded-Proto. Behind a TLS-terminating proxy, list the
    proxy in KnownProxies before first start (D-53).

Fixed

  • A library scan follows symbolic links, as upstream does. A linked media
    file or a linked directory, also one outside the library root, enters the
    library under the link path; before, the scan left every link out. A
    dangling link is skipped with a warning. A directory link to the directory
    that holds it or to one of its ancestors is skipped with a warning (D-86).
    A file link's snapshot now carries the facts of its target, so playback and
    probing check the target file.
  • The library scan logs a folder failure when the folder fails. Before, the
    scanner folder lines came only after the whole scan ended, so a scan that
    stalled logged no failure at all (#702).
  • A library scan keeps a folder that holds two names that differ only in
    case, such as Live and live on a case-sensitive NFS or ZFS share. Both
    names gave the same item ID, and the whole folder failed on every scan: an
    artist's discography, a season, or at the library root the whole library
    stayed missing. The scan now keeps the first name in ordinal order and logs
    the other as skipped (D-85). A directory entry whose file status cannot be
    read is skipped with a warning; before, one such entry failed the listing
    of its whole directory (#702).
  • A multi-disc album is one album, as in Jellyfin. An album folder whose
    tracks are in disc folders (CD 01, Disc 1, Digital Media 01, and the
    other Jellyfin disc names) is the MusicAlbum, its parent folder is the
    artist, and the disc folders are plain folders. The album lists the tracks
    of every disc, its track count includes every disc, and each track shows
    the album. Before, each disc folder was an album named after the folder,
    with no album artist. A library scan replaces those albums (#703).
  • The library scan ignores Jellyfin trickplay directories, as Jellyfin does.
    With "save trickplay with media" on, Jellyfin writes a
    <video>.trickplay/ directory next to each video. Deadfin indexed these
    directories and their tile directories as Folder items that showed in
    browse and search. The next scan removes Folder items that an earlier scan
    made for them (#704).
  • HLS copies a Dolby Vision profile 7 (dual-layer) HEVC stream as HDR10 for a
    client that lists HDR10 but not DOVIWithEL in its range types. The copy
    removes the RPU and the enhancement layer with hevc_metadata=remove_dovi
    (or dovi_rpu=strip) and the master playlist offers an hvc1 variant with
    VIDEO-RANGE=PQ, as upstream does. Before, such a client got a 4K SDR
    H.264 tone-mapped transcode. Startup probes which removal filters ffmpeg
    has. The same port strips HDR10+ from a profile 8.1 HDR10+ copy for a
    Dolby Vision client, and Dolby Vision from an invalid configuration (#586,
    D-84).
  • import-jellyfin reads a Jellyfin database in WAL mode from the read-only
    /import mount that the import guide uses. The importer opens the stopped
    copy immutable, so SQLite creates no jellyfin.db-shm next to it. A
    non-empty jellyfin.db-wal stops the import with a message to stop
    Jellyfin and copy again (#697).
  • HLS plays an audio track that starts late. A track whose first packet is
    more than 1 s into the file is encoded with leading silence instead of
    copied: AAC when the client accepts it, else AC3 or E-AC3. A copied late
    AC3 track gave an init segment without dac3 and first segments without
    audio, and AVPlayer failed the item at once. The Italian stereo track of a
    4K remux starts at 33.55 s (#681, D-82).
  • Embedded text subtitles of large files load. One ffmpeg pass extracts
    every embedded subtitle stream of a file into the subtitle cache, text
    streams included, as upstream does. The first request waits for the pass
    under SubtitleExtractionTimeoutMinutes; later requests read the cache. The
    forced track of a 4K remux returned 500 after 30 s (#676, D-52).
  • GET /UserItems/Resume and GET /Users/{userId}/Items/Resume honor
    parentId: they return only the in-progress items under the series,
    season, folder, library, collection, or playlist. Before, they returned the
    whole resume list, so the series Play button in Swiftfin played an
    unrelated movie. excludeActiveSessions now drops the items the user is
    playing, and the Latest exclusions apply only to the unscoped list, as
    upstream does (#674).
  • Sessions report the real play method. A report with no PlayMethod is
    Transcode while a transcoding job runs for its PlaySessionId, else
    DirectPlay, as upstream does. /Sessions carries TranscodingInfo for a
    running HLS job, so an HLS remux no longer shows as direct play (#635).
  • GET /Library/MediaFolders returns the library roots, as upstream does:
    the enabled collection folders and the hidden playlists folder, ordered by
    sort name, with the isHidden filter, for administrators only. Seerr and
    other Jellyfin tools that list libraries this way work without a fallback.
    The playlists folder projects as ManualPlaylistsFolder with
    CollectionType playlists (#596).
  • Comma-delimited enum query parameters drop unknown values, as upstream
    does. Infuse home rows (/Items/Latest with an Emby field) load again.
  • GET /MediaSegments/{itemId} returns an empty QueryResult for a known
    item (Infuse called it on every play).
  • HLS stream copy of Dolby Vision profile 7 (DOVIWithEL) is tagged hvc1,
    so the init segment matches the hvc1 master playlist and AVPlayer can
    decode the HDR10 base layer (D-65).
  • The H.264 level in the HLS master playlist matches the level the encoder
    writes (D-66).
  • The HLS throttler and the transcode cache limits pause ffmpeg again.
    jellyfin-ffmpeg 8 does not pause on the old key, so a fast remux kept writing
    segments far ahead of playback.
  • A user with access to only some libraries can open a person, genre or
    studio by its ID, as upstream does. Cast portraits returned 404 for these
    users. Lists keep the library restriction.

Image

docker pull ghcr.io/deadfin-org/deadfin:v0.3.0-rc.15
docker pull ghcr.io/deadfin-org/deadfin@sha256:f698010779c31380a86d9c15d7df72a16f3716e9bffa90d44bc36902e0bc1b38

Platforms: linux/amd64, linux/arm64. See docs/alpha to install.

Verify

The image carries a build provenance attestation and an SPDX SBOM attestation for each architecture. The SBOMs are attached to this release.

gh attestation verify oci://ghcr.io/deadfin-org/deadfin@sha256...
Read more

v0.3.0-rc.14

v0.3.0-rc.14 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 19 Oct 00:07
v0.3.0-rc.14
5e45545

v0.3.0 is the first public alpha of Deadfin.

Highlights

  • The image includes deadfin-web. Deadfin serves the bundled web client
    (v0.3.0-rc.4) at /web/ with no extra download. To use jellyfin-web
    instead, put its files in ./deadfin/web and mount that directory at
    /var/lib/deadfin/web; a <data root>/web with an index.html replaces
    the bundled client. An existing ./deadfin/web mount keeps working and
    keeps its own files: remove the mount to use the bundled deadfin-web.
  • Audio and subtitle choice carries to the next episode (D-36). When you
    pick a language or a subtitle track in one episode, the next episode of the
    same series starts with the matching tracks. Subtitles off also carries.
  • Anime search finds every title (D-48). Search matches the English,
    romaji, native and alias titles from AniList and AniDB, with a kana/romaji
    fold. "Shingeki" and "進撃" both find "Attack on Titan".
  • PostgreSQL support. SQLite stays the default. Set
    DEADFIN_DATABASE_URL (or --database-url) to a postgres:// URL to run
    on PostgreSQL. See docs/alpha/install.md.
  • Security fixes from the release-candidate review: sign-out revokes the
    token, video attachments are scoped to the user, the image downloader
    refuses special-purpose address ranges, and the toolchain is Go 1.26.9.

Added

  • CHANGELOG.md. Each GitHub Release body comes from its section here.
  • Release images carry a build provenance attestation and an SPDX SBOM for
    each architecture. The SBOMs are attached to the GitHub Release.
  • The :alpha image tag. It follows the newest release or release
    candidate. The :latest tag follows the newest release (no -rc.N), so
    v0.3.0 publishes it first.
  • Person pages show a biography, birth date, death date and birthplace from
    TMDb. Opening a person without metadata fetches it, and the "Refresh
    People" scheduled task fetches it for every person not yet refreshed
    (D-74). Cast and crew keep their TMDb person ID. This needs a TMDb API
    key (D-11).
  • The integrations guide: connect Seerr, Sonarr, Radarr and Bazarr beside
    Jellyfin and after the cutover, with a script that moves Seerr users to
    their Deadfin IDs. See
    docs/alpha/integrations.md.

Changed

  • The startup log names the web client in use: its directory, the source
    (data root or bundled) and the version from its build.json.
  • The quick start and the install guide put TMDb API key setup first.
  • DEADFIN_DATA_DIR sets the data root. JELLYFIN_DATA_DIR stays as the
    fallback. The image sets its default, /var/lib/deadfin, in JELLYFIN_DATA_DIR,
    so a deployment that sets either variable overrides it. Deadfin
    logs a warning for each set JELLYFIN_CONFIG_DIR, JELLYFIN_CACHE_DIR,
    JELLYFIN_LOG_DIR or JELLYFIN_WEB_DIR.

Security

  • POST /Sessions/Capabilities and POST /Sessions/Capabilities/Full
    refuse another user's session ID from a non-administrator caller (D-67).
  • /web/ responses send Referrer-Policy: no-referrer and
    X-Content-Type-Options: nosniff. When the served client is deadfin-web,
    they also send a restrictive Content-Security-Policy with
    frame-ancestors 'none' (D-68).
  • The one-time setup cookie is Secure when a KnownProxies peer reports
    HTTPS in X-Forwarded-Proto. Behind a TLS-terminating proxy, list the
    proxy in KnownProxies before first start (D-53).

Fixed

  • import-jellyfin reads a Jellyfin database in WAL mode from the read-only
    /import mount that the import guide uses. The importer opens the stopped
    copy immutable, so SQLite creates no jellyfin.db-shm next to it. A
    non-empty jellyfin.db-wal stops the import with a message to stop
    Jellyfin and copy again (#697).
  • HLS plays an audio track that starts late. A track whose first packet is
    more than 1 s into the file is encoded with leading silence instead of
    copied: AAC when the client accepts it, else AC3 or E-AC3. A copied late
    AC3 track gave an init segment without dac3 and first segments without
    audio, and AVPlayer failed the item at once. The Italian stereo track of a
    4K remux starts at 33.55 s (#681, D-82).
  • Embedded text subtitles of large files load. One ffmpeg pass extracts
    every embedded subtitle stream of a file into the subtitle cache, text
    streams included, as upstream does. The first request waits for the pass
    under SubtitleExtractionTimeoutMinutes; later requests read the cache. The
    forced track of a 4K remux returned 500 after 30 s (#676, D-52).
  • GET /UserItems/Resume and GET /Users/{userId}/Items/Resume honor
    parentId: they return only the in-progress items under the series,
    season, folder, library, collection, or playlist. Before, they returned the
    whole resume list, so the series Play button in Swiftfin played an
    unrelated movie. excludeActiveSessions now drops the items the user is
    playing, and the Latest exclusions apply only to the unscoped list, as
    upstream does (#674).
  • Sessions report the real play method. A report with no PlayMethod is
    Transcode while a transcoding job runs for its PlaySessionId, else
    DirectPlay, as upstream does. /Sessions carries TranscodingInfo for a
    running HLS job, so an HLS remux no longer shows as direct play (#635).
  • GET /Library/MediaFolders returns the library roots, as upstream does:
    the enabled collection folders and the hidden playlists folder, ordered by
    sort name, with the isHidden filter, for administrators only. Seerr and
    other Jellyfin tools that list libraries this way work without a fallback.
    The playlists folder projects as ManualPlaylistsFolder with
    CollectionType playlists (#596).
  • Comma-delimited enum query parameters drop unknown values, as upstream
    does. Infuse home rows (/Items/Latest with an Emby field) load again.
  • GET /MediaSegments/{itemId} returns an empty QueryResult for a known
    item (Infuse called it on every play).
  • HLS stream copy of Dolby Vision profile 7 (DOVIWithEL) is tagged hvc1,
    so the init segment matches the hvc1 master playlist and AVPlayer can
    decode the HDR10 base layer (D-65).
  • The H.264 level in the HLS master playlist matches the level the encoder
    writes (D-66).
  • The HLS throttler and the transcode cache limits pause ffmpeg again.
    jellyfin-ffmpeg 8 does not pause on the old key, so a fast remux kept writing
    segments far ahead of playback.
  • A user with access to only some libraries can open a person, genre or
    studio by its ID, as upstream does. Cast portraits returned 404 for these
    users. Lists keep the library restriction.

Image

docker pull ghcr.io/deadfin-org/deadfin:v0.3.0-rc.14
docker pull ghcr.io/deadfin-org/deadfin@sha256:c59746eb4e4b40b5a2e9c3c049bf8cd6d8ab1e20e34baa64908e8bbcfa1da4e9

Platforms: linux/amd64, linux/arm64. See docs/alpha to install.

Verify

The image carries a build provenance attestation and an SPDX SBOM attestation for each architecture. The SBOMs are attached to this release.

gh attestation verify oci://ghcr.io/deadfin-org/deadfin@sha256:c59746eb4e4b40b5a2e9c3c049bf8cd6d8ab1e20e34baa64908e8bbcfa1da4e9 --repo deadfin-org/deadfin

v0.3.0-rc.13

v0.3.0-rc.13 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 18 Oct 23:11
v0.3.0-rc.13
5706fd4

v0.3.0 is the first public alpha of Deadfin.

Highlights

  • The image includes deadfin-web. Deadfin serves the bundled web client
    (v0.3.0-rc.4) at /web/ with no extra download. To use jellyfin-web
    instead, put its files in ./deadfin/web and mount that directory at
    /var/lib/deadfin/web; a <data root>/web with an index.html replaces
    the bundled client. An existing ./deadfin/web mount keeps working and
    keeps its own files: remove the mount to use the bundled deadfin-web.
  • Audio and subtitle choice carries to the next episode (D-36). When you
    pick a language or a subtitle track in one episode, the next episode of the
    same series starts with the matching tracks. Subtitles off also carries.
  • Anime search finds every title (D-48). Search matches the English,
    romaji, native and alias titles from AniList and AniDB, with a kana/romaji
    fold. "Shingeki" and "進撃" both find "Attack on Titan".
  • PostgreSQL support. SQLite stays the default. Set
    DEADFIN_DATABASE_URL (or --database-url) to a postgres:// URL to run
    on PostgreSQL. See docs/alpha/install.md.
  • Security fixes from the release-candidate review: sign-out revokes the
    token, video attachments are scoped to the user, the image downloader
    refuses special-purpose address ranges, and the toolchain is Go 1.26.9.

Added

  • CHANGELOG.md. Each GitHub Release body comes from its section here.
  • Release images carry a build provenance attestation and an SPDX SBOM for
    each architecture. The SBOMs are attached to the GitHub Release.
  • The :alpha image tag. It follows the newest release or release
    candidate. The :latest tag follows the newest release (no -rc.N), so
    v0.3.0 publishes it first.
  • Person pages show a biography, birth date, death date and birthplace from
    TMDb. Opening a person without metadata fetches it, and the "Refresh
    People" scheduled task fetches it for every person not yet refreshed
    (D-74). Cast and crew keep their TMDb person ID. This needs a TMDb API
    key (D-11).
  • The integrations guide: connect Seerr, Sonarr, Radarr and Bazarr beside
    Jellyfin and after the cutover, with a script that moves Seerr users to
    their Deadfin IDs. See
    docs/alpha/integrations.md.

Changed

  • The startup log names the web client in use: its directory, the source
    (data root or bundled) and the version from its build.json.
  • The quick start and the install guide put TMDb API key setup first.
  • DEADFIN_DATA_DIR sets the data root. JELLYFIN_DATA_DIR stays as the
    fallback. The image sets its default, /var/lib/deadfin, in JELLYFIN_DATA_DIR,
    so a deployment that sets either variable overrides it. Deadfin
    logs a warning for each set JELLYFIN_CONFIG_DIR, JELLYFIN_CACHE_DIR,
    JELLYFIN_LOG_DIR or JELLYFIN_WEB_DIR.

Security

  • POST /Sessions/Capabilities and POST /Sessions/Capabilities/Full
    refuse another user's session ID from a non-administrator caller (D-67).
  • /web/ responses send Referrer-Policy: no-referrer and
    X-Content-Type-Options: nosniff. When the served client is deadfin-web,
    they also send a restrictive Content-Security-Policy with
    frame-ancestors 'none' (D-68).
  • The one-time setup cookie is Secure when a KnownProxies peer reports
    HTTPS in X-Forwarded-Proto. Behind a TLS-terminating proxy, list the
    proxy in KnownProxies before first start (D-53).

Fixed

  • HLS plays an audio track that starts late. A track whose first packet is
    more than 1 s into the file is encoded with leading silence instead of
    copied: AAC when the client accepts it, else AC3 or E-AC3. A copied late
    AC3 track gave an init segment without dac3 and first segments without
    audio, and AVPlayer failed the item at once. The Italian stereo track of a
    4K remux starts at 33.55 s (#681, D-82).
  • Embedded text subtitles of large files load. One ffmpeg pass extracts
    every embedded subtitle stream of a file into the subtitle cache, text
    streams included, as upstream does. The first request waits for the pass
    under SubtitleExtractionTimeoutMinutes; later requests read the cache. The
    forced track of a 4K remux returned 500 after 30 s (#676, D-52).
  • GET /UserItems/Resume and GET /Users/{userId}/Items/Resume honor
    parentId: they return only the in-progress items under the series,
    season, folder, library, collection, or playlist. Before, they returned the
    whole resume list, so the series Play button in Swiftfin played an
    unrelated movie. excludeActiveSessions now drops the items the user is
    playing, and the Latest exclusions apply only to the unscoped list, as
    upstream does (#674).
  • Sessions report the real play method. A report with no PlayMethod is
    Transcode while a transcoding job runs for its PlaySessionId, else
    DirectPlay, as upstream does. /Sessions carries TranscodingInfo for a
    running HLS job, so an HLS remux no longer shows as direct play (#635).
  • GET /Library/MediaFolders returns the library roots, as upstream does:
    the enabled collection folders and the hidden playlists folder, ordered by
    sort name, with the isHidden filter, for administrators only. Seerr and
    other Jellyfin tools that list libraries this way work without a fallback.
    The playlists folder projects as ManualPlaylistsFolder with
    CollectionType playlists (#596).
  • Comma-delimited enum query parameters drop unknown values, as upstream
    does. Infuse home rows (/Items/Latest with an Emby field) load again.
  • GET /MediaSegments/{itemId} returns an empty QueryResult for a known
    item (Infuse called it on every play).
  • HLS stream copy of Dolby Vision profile 7 (DOVIWithEL) is tagged hvc1,
    so the init segment matches the hvc1 master playlist and AVPlayer can
    decode the HDR10 base layer (D-65).
  • The H.264 level in the HLS master playlist matches the level the encoder
    writes (D-66).
  • The HLS throttler and the transcode cache limits pause ffmpeg again.
    jellyfin-ffmpeg 8 does not pause on the old key, so a fast remux kept writing
    segments far ahead of playback.
  • A user with access to only some libraries can open a person, genre or
    studio by its ID, as upstream does. Cast portraits returned 404 for these
    users. Lists keep the library restriction.

Image

docker pull ghcr.io/deadfin-org/deadfin:v0.3.0-rc.13
docker pull ghcr.io/deadfin-org/deadfin@sha256:ed9fb53ee3dfa5d7b0980f46d9b160d16843a73b9e1fdb2f5734363fd3d0b2e0

Platforms: linux/amd64, linux/arm64. See docs/alpha to install.

Verify

The image carries a build provenance attestation and an SPDX SBOM attestation for each architecture. The SBOMs are attached to this release.

gh attestation verify oci://ghcr.io/deadfin-org/deadfin@sha256:ed9fb53ee3dfa5d7b0980f46d9b160d16843a73b9e1fdb2f5734363fd3d0b2e0 --repo deadfin-org/deadfin