diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index e1900d583..2e39990b6 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,4 +1,4 @@ # Joshua must review all changes to deployment and build.sh -.ci/* @joshuaboniface -deployment/* @joshuaboniface -build.sh @joshuaboniface +.ci/* @dannymichel +deployment/* @dannymichel +build.sh @dannymichel diff --git a/.github/renovate.json b/.github/renovate.json index 5ca683876..736a972f5 100644 --- a/.github/renovate.json +++ b/.github/renovate.json @@ -1,6 +1,6 @@ { "$schema": "https://docs.renovatebot.com/renovate-schema.json", "extends": [ - "github>jellyfin/.github//renovate-presets/dotnet" + "github>vesoapp/.github//renovate-presets/dotnet" ] } diff --git a/.github/workflows/automation.yml b/.github/workflows/automation.yml index 4b5571c77..d23601d56 100644 --- a/.github/workflows/automation.yml +++ b/.github/workflows/automation.yml @@ -12,7 +12,7 @@ jobs: label: name: Labeling runs-on: ubuntu-latest - if: ${{ github.repository == 'jellyfin/jellyfin' }} + if: ${{ github.repository == 'vesoapp/veso' }} steps: - name: Apply label uses: eps1lon/actions-label-merge-conflict@fd1f295ee7443d13745804bc49fe158e240f6c6e # tag=v2.1.0 @@ -24,7 +24,7 @@ jobs: project: name: Project board runs-on: ubuntu-latest - if: ${{ github.repository == 'jellyfin/jellyfin' }} + if: ${{ github.repository == 'vesoapp/veso' }} steps: - name: Remove from 'Current Release' project uses: alex-page/github-project-automation-plus@7ffb872c64bd809d23563a130a0a97d01dfa8f43 # v0.8.3 diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index d5dcb785c..bf0da51d2 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -20,7 +20,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@24cb9080177205b6e8c946b17badbe402adc938f # v3 + uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3 - name: Setup .NET uses: actions/setup-dotnet@607fce577a46308457984d59e4954e075820f10a # tag=v3 with: diff --git a/.github/workflows/commands.yml b/.github/workflows/commands.yml index c0b365b02..99d1db88b 100644 --- a/.github/workflows/commands.yml +++ b/.github/workflows/commands.yml @@ -13,7 +13,7 @@ permissions: {} jobs: rebase: name: Rebase - if: github.event.issue.pull_request != '' && contains(github.event.comment.body, '@jellyfin-bot rebase') && github.event.comment.author_association == 'MEMBER' + if: github.event.issue.pull_request != '' && contains(github.event.comment.body, '@veso-bot rebase') && github.event.comment.author_association == 'MEMBER' runs-on: ubuntu-latest steps: - name: Notify as seen @@ -24,7 +24,7 @@ jobs: reactions: '+1' - name: Checkout the latest code - uses: actions/checkout@24cb9080177205b6e8c946b17badbe402adc938f # v3 + uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3 with: token: ${{ secrets.JF_BOT_TOKEN }} fetch-depth: 0 @@ -39,7 +39,7 @@ jobs: contents: read name: Check Backport - if: ${{ ( github.event.issue.pull_request && contains(github.event.comment.body, '@jellyfin-bot check backport') ) || github.event.label.name == 'stable backport' || contains(github.event.pull_request.labels.*.name, 'stable backport' ) }} + if: ${{ ( github.event.issue.pull_request && contains(github.event.comment.body, '@veso-bot check backport') ) || github.event.label.name == 'stable backport' || contains(github.event.pull_request.labels.*.name, 'stable backport' ) }} runs-on: ubuntu-latest steps: - name: Notify as seen @@ -51,7 +51,7 @@ jobs: reactions: eyes - name: Checkout the latest code - uses: actions/checkout@24cb9080177205b6e8c946b17badbe402adc938f # v3 + uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3 with: token: ${{ secrets.JF_BOT_TOKEN }} fetch-depth: 0 diff --git a/.github/workflows/openapi.yml b/.github/workflows/openapi.yml index a67ce90d2..0f8221b76 100644 --- a/.github/workflows/openapi.yml +++ b/.github/workflows/openapi.yml @@ -14,7 +14,7 @@ jobs: permissions: read-all steps: - name: Checkout repository - uses: actions/checkout@24cb9080177205b6e8c946b17badbe402adc938f # v3 + uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3 with: ref: ${{ github.event.pull_request.head.sha }} repository: ${{ github.event.pull_request.head.repo.full_name }} @@ -39,7 +39,7 @@ jobs: permissions: read-all steps: - name: Checkout repository - uses: actions/checkout@24cb9080177205b6e8c946b17badbe402adc938f # v3 + uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3 with: ref: ${{ github.event.pull_request.head.sha }} repository: ${{ github.event.pull_request.head.repo.full_name }} diff --git a/.github/workflows/repo-stale.yaml b/.github/workflows/repo-stale.yaml index 7f6fcffed..a9895cd23 100644 --- a/.github/workflows/repo-stale.yaml +++ b/.github/workflows/repo-stale.yaml @@ -10,7 +10,7 @@ permissions: jobs: stale: runs-on: ubuntu-latest - if: ${{ contains(github.repository, 'jellyfin/') }} + if: ${{ contains(github.repository, 'vesoapp/') }} steps: - uses: actions/stale@6f05e4244c9a0b2ed3401882b05d701dd0a7289b # v7 with: diff --git a/.gitignore b/.gitignore index d5a0367bf..7a4c6353d 100644 --- a/.gitignore +++ b/.gitignore @@ -277,3 +277,4 @@ apiclient/generated # Omnisharp crash logs mono_crash.*.json +.DS_Store diff --git a/Dockerfile b/Dockerfile index e51d285e1..8c73a97fe 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,8 +7,8 @@ ARG DOTNET_VERSION=7.0 FROM node:lts-alpine as web-builder ARG JELLYFIN_WEB_VERSION=master RUN apk add curl git zlib zlib-dev autoconf g++ make libpng-dev gifsicle alpine-sdk automake libtool make gcc musl-dev nasm python3 \ - && curl -L https://github.com/jellyfin/jellyfin-web/archive/${JELLYFIN_WEB_VERSION}.tar.gz | tar zxf - \ - && cd jellyfin-web-* \ + && curl -L https://github.com/vesoapp/veso-web/archive/${JELLYFIN_WEB_VERSION}.tar.gz | tar zxf - \ + && cd veso-web-* \ && npm ci --no-audit --unsafe-perm \ && npm run build:production \ && mv dist /dist diff --git a/Dockerfile.arm b/Dockerfile.arm index 46a3e9b99..9188b5fca 100644 --- a/Dockerfile.arm +++ b/Dockerfile.arm @@ -8,8 +8,8 @@ ARG DOTNET_VERSION=7.0 FROM node:lts-alpine as web-builder ARG JELLYFIN_WEB_VERSION=master RUN apk add curl git zlib zlib-dev autoconf g++ make libpng-dev gifsicle alpine-sdk automake libtool make gcc musl-dev nasm python3 \ - && curl -L https://github.com/jellyfin/jellyfin-web/archive/${JELLYFIN_WEB_VERSION}.tar.gz | tar zxf - \ - && cd jellyfin-web-* \ + && curl -L https://github.com/vesoapp/veso-web/archive/${JELLYFIN_WEB_VERSION}.tar.gz | tar zxf - \ + && cd veso-web-* \ && npm ci --no-audit --unsafe-perm \ && npm run build:production \ && mv dist /dist diff --git a/Dockerfile.arm64 b/Dockerfile.arm64 index 4f9d5e1fd..86173b1d1 100644 --- a/Dockerfile.arm64 +++ b/Dockerfile.arm64 @@ -8,8 +8,8 @@ ARG DOTNET_VERSION=7.0 FROM node:lts-alpine as web-builder ARG JELLYFIN_WEB_VERSION=master RUN apk add curl git zlib zlib-dev autoconf g++ make libpng-dev gifsicle alpine-sdk automake libtool make gcc musl-dev nasm python3 \ - && curl -L https://github.com/jellyfin/jellyfin-web/archive/${JELLYFIN_WEB_VERSION}.tar.gz | tar zxf - \ - && cd jellyfin-web-* \ + && curl -L https://github.com/vesoapp/veso-web/archive/${JELLYFIN_WEB_VERSION}.tar.gz | tar zxf - \ + && cd veso-web-* \ && npm ci --no-audit --unsafe-perm \ && npm run build:production \ && mv dist /dist diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 080c44829..cae808a89 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -597,8 +597,7 @@ protected virtual void RegisterServices(IServiceCollection serviceCollection) serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); - serviceCollection.AddSingleton(); - serviceCollection.AddSingleton(); + serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); diff --git a/MediaBrowser.MediaEncoding/Subtitles/AssParser.cs b/MediaBrowser.MediaEncoding/Subtitles/AssParser.cs new file mode 100644 index 000000000..08ee5c72e --- /dev/null +++ b/MediaBrowser.MediaEncoding/Subtitles/AssParser.cs @@ -0,0 +1,19 @@ +using Microsoft.Extensions.Logging; +using Nikse.SubtitleEdit.Core.SubtitleFormats; + +namespace MediaBrowser.MediaEncoding.Subtitles +{ + /// + /// Advanced SubStation Alpha subtitle parser. + /// + public class AssParser : SubtitleEditParser + { + /// + /// Initializes a new instance of the class. + /// + /// The logger. + public AssParser(ILogger logger) : base(logger) + { + } + } +} diff --git a/MediaBrowser.MediaEncoding/Subtitles/ISubtitleParser.cs b/MediaBrowser.MediaEncoding/Subtitles/ISubtitleParser.cs index bd13437fb..c0023ebf2 100644 --- a/MediaBrowser.MediaEncoding/Subtitles/ISubtitleParser.cs +++ b/MediaBrowser.MediaEncoding/Subtitles/ISubtitleParser.cs @@ -1,6 +1,7 @@ #pragma warning disable CS1591 using System.IO; +using System.Threading; using MediaBrowser.Model.MediaInfo; namespace MediaBrowser.MediaEncoding.Subtitles @@ -11,15 +12,8 @@ public interface ISubtitleParser /// Parses the specified stream. /// /// The stream. - /// The file extension. + /// The cancellation token. /// SubtitleTrackInfo. - SubtitleTrackInfo Parse(Stream stream, string fileExtension); - - /// - /// Determines whether the file extension is supported by the parser. - /// - /// The file extension. - /// A value indicating whether the file extension is supported. - bool SupportsFileExtension(string fileExtension); + SubtitleTrackInfo Parse(Stream stream, CancellationToken cancellationToken); } } diff --git a/MediaBrowser.MediaEncoding/Subtitles/SrtParser.cs b/MediaBrowser.MediaEncoding/Subtitles/SrtParser.cs new file mode 100644 index 000000000..78d54ca51 --- /dev/null +++ b/MediaBrowser.MediaEncoding/Subtitles/SrtParser.cs @@ -0,0 +1,19 @@ +using Microsoft.Extensions.Logging; +using Nikse.SubtitleEdit.Core.SubtitleFormats; + +namespace MediaBrowser.MediaEncoding.Subtitles +{ + /// + /// SubRip subtitle parser. + /// + public class SrtParser : SubtitleEditParser + { + /// + /// Initializes a new instance of the class. + /// + /// The logger. + public SrtParser(ILogger logger) : base(logger) + { + } + } +} diff --git a/MediaBrowser.MediaEncoding/Subtitles/SsaParser.cs b/MediaBrowser.MediaEncoding/Subtitles/SsaParser.cs new file mode 100644 index 000000000..17c2ae40e --- /dev/null +++ b/MediaBrowser.MediaEncoding/Subtitles/SsaParser.cs @@ -0,0 +1,19 @@ +using Microsoft.Extensions.Logging; +using Nikse.SubtitleEdit.Core.SubtitleFormats; + +namespace MediaBrowser.MediaEncoding.Subtitles +{ + /// + /// SubStation Alpha subtitle parser. + /// + public class SsaParser : SubtitleEditParser + { + /// + /// Initializes a new instance of the class. + /// + /// The logger. + public SsaParser(ILogger logger) : base(logger) + { + } + } +} diff --git a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEditParser.cs b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEditParser.cs index 0d4489517..52c1b6467 100644 --- a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEditParser.cs +++ b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEditParser.cs @@ -1,12 +1,12 @@ -using System; -using System.Collections.Generic; using System.Globalization; using System.IO; using System.Linq; +using System.Threading; using Jellyfin.Extensions; using MediaBrowser.Model.MediaInfo; using Microsoft.Extensions.Logging; using Nikse.SubtitleEdit.Core.Common; +using ILogger = Microsoft.Extensions.Logging.ILogger; using SubtitleFormat = Nikse.SubtitleEdit.Core.SubtitleFormats.SubtitleFormat; namespace MediaBrowser.MediaEncoding.Subtitles @@ -14,57 +14,31 @@ namespace MediaBrowser.MediaEncoding.Subtitles /// /// SubStation Alpha subtitle parser. /// - public class SubtitleEditParser : ISubtitleParser + /// The . + public abstract class SubtitleEditParser : ISubtitleParser + where T : SubtitleFormat, new() { - private readonly ILogger _logger; - private readonly Dictionary _subtitleFormats; + private readonly ILogger _logger; /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The logger. - public SubtitleEditParser(ILogger logger) + protected SubtitleEditParser(ILogger logger) { _logger = logger; - _subtitleFormats = GetSubtitleFormats() - .Where(subtitleFormat => !string.IsNullOrEmpty(subtitleFormat.Extension)) - .GroupBy(subtitleFormat => subtitleFormat.Extension.TrimStart('.'), StringComparer.OrdinalIgnoreCase) - .ToDictionary(g => g.Key, g => g.ToArray(), StringComparer.OrdinalIgnoreCase); } /// - public SubtitleTrackInfo Parse(Stream stream, string fileExtension) + public SubtitleTrackInfo Parse(Stream stream, CancellationToken cancellationToken) { var subtitle = new Subtitle(); + var subRip = new T(); var lines = stream.ReadAllLines().ToList(); - - if (!_subtitleFormats.TryGetValue(fileExtension, out var subtitleFormats)) - { - throw new ArgumentException($"Unsupported file extension: {fileExtension}", nameof(fileExtension)); - } - - foreach (var subtitleFormat in subtitleFormats) + subRip.LoadSubtitle(subtitle, lines, "untitled"); + if (subRip.ErrorCount > 0) { - _logger.LogDebug( - "Trying to parse '{FileExtension}' subtitle using the {SubtitleFormatParser} format parser", - fileExtension, - subtitleFormat.Name); - subtitleFormat.LoadSubtitle(subtitle, lines, fileExtension); - if (subtitleFormat.ErrorCount == 0) - { - break; - } - - _logger.LogError( - "{ErrorCount} errors encountered while parsing '{FileExtension}' subtitle using the {SubtitleFormatParser} format parser", - subtitleFormat.ErrorCount, - fileExtension, - subtitleFormat.Name); - } - - if (subtitle.Paragraphs.Count == 0) - { - throw new ArgumentException("Unsupported format: " + fileExtension); + _logger.LogError("{ErrorCount} errors encountered while parsing subtitle", subRip.ErrorCount); } var trackInfo = new SubtitleTrackInfo(); @@ -83,36 +57,5 @@ public SubtitleTrackInfo Parse(Stream stream, string fileExtension) trackInfo.TrackEvents = trackEvents; return trackInfo; } - - /// - public bool SupportsFileExtension(string fileExtension) - => _subtitleFormats.ContainsKey(fileExtension); - - private IEnumerable GetSubtitleFormats() - { - var subtitleFormats = new List(); - var assembly = typeof(SubtitleFormat).Assembly; - - foreach (var type in assembly.GetTypes()) - { - if (!type.IsSubclassOf(typeof(SubtitleFormat)) || type.IsAbstract) - { - continue; - } - - try - { - // It shouldn't be null, but the exception is caught if it is - var subtitleFormat = (SubtitleFormat)Activator.CreateInstance(type, true)!; - subtitleFormats.Add(subtitleFormat); - } - catch (Exception ex) - { - _logger.LogWarning(ex, "Failed to create instance of the subtitle format {SubtitleFormatType}", type.Name); - } - } - - return subtitleFormats; - } } } diff --git a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs index 90bc49132..9e43b9129 100644 --- a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs +++ b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs @@ -35,7 +35,6 @@ public sealed class SubtitleEncoder : ISubtitleEncoder private readonly IMediaEncoder _mediaEncoder; private readonly IHttpClientFactory _httpClientFactory; private readonly IMediaSourceManager _mediaSourceManager; - private readonly ISubtitleParser _subtitleParser; /// /// The _semaphoreLocks. @@ -49,8 +48,7 @@ public sealed class SubtitleEncoder : ISubtitleEncoder IFileSystem fileSystem, IMediaEncoder mediaEncoder, IHttpClientFactory httpClientFactory, - IMediaSourceManager mediaSourceManager, - ISubtitleParser subtitleParser) + IMediaSourceManager mediaSourceManager) { _logger = logger; _appPaths = appPaths; @@ -58,7 +56,6 @@ public sealed class SubtitleEncoder : ISubtitleEncoder _mediaEncoder = mediaEncoder; _httpClientFactory = httpClientFactory; _mediaSourceManager = mediaSourceManager; - _subtitleParser = subtitleParser; } private string SubtitleCachePath => Path.Combine(_appPaths.DataPath, "subtitles"); @@ -76,7 +73,8 @@ public sealed class SubtitleEncoder : ISubtitleEncoder try { - var trackInfo = _subtitleParser.Parse(stream, inputFormat); + var reader = GetReader(inputFormat); + var trackInfo = reader.Parse(stream, cancellationToken); FilterEvents(trackInfo, startTimeTicks, endTimeTicks, preserveOriginalTimestamps); @@ -238,8 +236,7 @@ await ExtractTextSubtitle(mediaSource, subtitleStream, outputCodec, outputPath, var currentFormat = (Path.GetExtension(subtitleStream.Path) ?? subtitleStream.Codec) .TrimStart('.'); - // Fallback to ffmpeg conversion - if (!_subtitleParser.SupportsFileExtension(currentFormat)) + if (!TryGetReader(currentFormat, out _)) { // Convert var outputPath = GetSubtitleCachePath(mediaSource, subtitleStream.Index, ".srt"); @@ -265,6 +262,40 @@ await ExtractTextSubtitle(mediaSource, subtitleStream, outputCodec, outputPath, }; } + private bool TryGetReader(string format, [NotNullWhen(true)] out ISubtitleParser? value) + { + if (string.Equals(format, SubtitleFormat.SRT, StringComparison.OrdinalIgnoreCase)) + { + value = new SrtParser(_logger); + return true; + } + + if (string.Equals(format, SubtitleFormat.SSA, StringComparison.OrdinalIgnoreCase)) + { + value = new SsaParser(_logger); + return true; + } + + if (string.Equals(format, SubtitleFormat.ASS, StringComparison.OrdinalIgnoreCase)) + { + value = new AssParser(_logger); + return true; + } + + value = null; + return false; + } + + private ISubtitleParser GetReader(string format) + { + if (TryGetReader(format, out var reader)) + { + return reader; + } + + throw new ArgumentException("Unsupported format: " + format); + } + private bool TryGetWriter(string format, [NotNullWhen(true)] out ISubtitleWriter? value) { ArgumentException.ThrowIfNullOrEmpty(format); diff --git a/README.md b/README.md index 2362741b4..d225e241e 100644 --- a/README.md +++ b/README.md @@ -1,176 +1,33 @@ -

Jellyfin

+

Veso

The Free Software Media System

- ---- +

A Jellyfin Fork with Fixes and Usability in Mind

-Logo Banner -
-
- -GPL 2.0 License - - -Current Release - - -Translation Status - - -Azure Builds - - -Docker Pull Count - -
- -Donate - - -Submit Feature Requests - - -Chat on Matrix - - -Join our Subreddit - - -Release RSS Feed - - -Master Commits RSS Feed - +Logo Banner

---- - -Jellyfin is a Free Software Media System that puts you in control of managing and streaming your media. It is an alternative to the proprietary Emby and Plex, to provide media from a dedicated server to end-user devices via multiple apps. Jellyfin is descended from Emby's 3.5.2 release and ported to the .NET Core framework to enable full cross-platform support. There are no strings attached, no premium licenses or features, and no hidden agendas: just a team who want to build something better and work together to achieve it. We welcome anyone who is interested in joining us in our quest! - -For further details, please see [our documentation page](https://jellyfin.org/docs/). To receive the latest updates, get help with Jellyfin, and join the community, please visit [one of our communication channels](https://jellyfin.org/docs/general/getting-help). For more information about the project, please see our [about page](https://jellyfin.org/docs/general/about). - -Want to get started?
-Check out our downloads page or our installation guide, then see our quick start guide. You can also build from source.
- -Something not working right?
-Open an Issue on GitHub.
- -Want to contribute?
-Check out our contributing choose-your-own-adventure to see where you can help, then see our contributing guide and our community standards.
- -New idea or improvement?
-Check out our feature request hub.
- -Don't see Jellyfin in your language?
-Check out our Weblate instance to help translate Jellyfin and its subprojects.
- - -Detailed Translation Status - - ---- - -## Jellyfin Server - -This repository contains the code for Jellyfin's backend server. Note that this is only one of many projects under the Jellyfin GitHub [organization](https://github.com/jellyfin/) on GitHub. If you want to contribute, you can start by checking out our [documentation](https://jellyfin.org/docs/general/contributing/index.html) to see what to work on. - -## Server Development - -These instructions will help you get set up with a local development environment in order to contribute to this repository. Before you start, please be sure to completely read our [guidelines on development contributions](https://jellyfin.org/docs/general/contributing/development.html). Note that this project is supported on all major operating systems except FreeBSD, which is still incompatible. +### docker-compose -### Prerequisites - -Before the project can be built, you must first install the [.NET 7.0 SDK](https://dotnet.microsoft.com/download/dotnet) on your system. - -Instructions to run this project from the command line are included here, but you will also need to install an IDE if you want to debug the server while it is running. Any IDE that supports .NET 6 development will work, but two options are recent versions of [Visual Studio](https://visualstudio.microsoft.com/downloads/) (at least 2022) and [Visual Studio Code](https://code.visualstudio.com/Download). - -[ffmpeg](https://github.com/jellyfin/jellyfin-ffmpeg) will also need to be installed. - -### Cloning the Repository - -After dependencies are installed you will need to clone a local copy of this repository. If you just want to run the server from source you can clone this repository directly, but if you are intending to contribute code changes to the project, you should [set up your own fork](https://jellyfin.org/docs/general/contributing/development.html#set-up-your-copy-of-the-repo) of the repository. The following example shows how you can clone the repository directly over HTTPS. - -```bash -git clone https://github.com/jellyfin/jellyfin.git ``` +version: '3.7' +services: + veso: + container_name: veso + environment: + - TZ=America/New_York + user: 1000:1000 + volumes: + - '/dev/dri:/dev/dri' + - '/path/to/config:/config' + - '/path/to/cache:/cache' + - '/path/to/media:/media' + ports: + - 8096:8096 + - 8920:8920 + devices: + - /dev/dri:/dev/dri + restart: unless-stopped + image: vesotv/veso:latest -### Installing the Web Client - -The server is configured to host the static files required for the [web client](https://github.com/jellyfin/jellyfin-web) in addition to serving the backend by default. Before you can run the server, you will need to get a copy of the web client since they are not included in this repository directly. - -Note that it is also possible to [host the web client separately](#hosting-the-web-client-separately) from the web server with some additional configuration, in which case you can skip this step. - -There are three options to get the files for the web client. - -1. Download one of the finished builds from the [Azure DevOps pipeline](https://dev.azure.com/jellyfin-project/jellyfin/_build?definitionId=27). You can download the build for a specific release by looking at the [branches tab](https://dev.azure.com/jellyfin-project/jellyfin/_build?definitionId=27&_a=summary&repositoryFilter=6&view=branches) of the pipelines page. -2. Build them from source following the instructions on the [jellyfin-web repository](https://github.com/jellyfin/jellyfin-web) -3. Get the pre-built files from an existing installation of the server. For example, with a Windows server installation the client files are located at `C:\Program Files\Jellyfin\Server\jellyfin-web` - -### Running The Server - -The following instructions will help you get the project up and running via the command line, or your preferred IDE. - -#### Running With Visual Studio - -To run the project with Visual Studio you can open the Solution (`.sln`) file and then press `F5` to run the server. - -#### Running With Visual Studio Code - -To run the project with Visual Studio Code you will first need to open the repository directory with Visual Studio Code using the `Open Folder...` option. - -Second, you need to [install the recommended extensions for the workspace](https://code.visualstudio.com/docs/editor/extension-gallery#_recommended-extensions). Note that extension recommendations are classified as either "Workspace Recommendations" or "Other Recommendations", but only the "Workspace Recommendations" are required. - -After the required extensions are installed, you can run the server by pressing `F5`. - -#### Running From The Command Line - -To run the server from the command line you can use the `dotnet run` command. The example below shows how to do this if you have cloned the repository into a directory named `jellyfin` (the default directory name) and should work on all operating systems. - -```bash -cd jellyfin # Move into the repository directory -dotnet run --project Jellyfin.Server --webdir /absolute/path/to/jellyfin-web/dist # Run the server startup project -``` - -A second option is to build the project and then run the resulting executable file directly. When running the executable directly you can easily add command line options. Add the `--help` flag to list details on all the supported command line options. - -1. Build the project - -```bash -dotnet build # Build the project -cd Jellyfin.Server/bin/Debug/net7.0 # Change into the build output directory ``` - -2. Execute the build output. On Linux, Mac, etc. use `./jellyfin` and on Windows use `jellyfin.exe`. - -### Running The Tests - -This repository also includes unit tests that are used to validate functionality as part of a CI pipeline on Azure. There are several ways to run these tests. - -1. Run tests from the command line using `dotnet test` -2. Run tests in Visual Studio using the [Test Explorer](https://docs.microsoft.com/en-us/visualstudio/test/run-unit-tests-with-test-explorer) -3. Run individual tests in Visual Studio Code using the associated [CodeLens annotation](https://github.com/OmniSharp/omnisharp-vscode/wiki/How-to-run-and-debug-unit-tests) - -### Advanced Configuration - -The following sections describe some more advanced scenarios for running the server from source that build upon the standard instructions above. - -#### Hosting The Web Client Separately - -It is not necessary to host the frontend web client as part of the backend server. Hosting these two components separately may be useful for frontend developers who would prefer to host the client in a separate webpack development server for a tighter development loop. See the [jellyfin-web](https://github.com/jellyfin/jellyfin-web#getting-started) repo for instructions on how to do this. - -To instruct the server not to host the web content, there is a `nowebclient` configuration flag that must be set. This can specified using the command line -switch `--nowebclient` or the environment variable `JELLYFIN_NOWEBCONTENT=true`. - -Since this is a common scenario, there is also a separate launch profile defined for Visual Studio called `Jellyfin.Server (nowebcontent)` that can be selected from the 'Start Debugging' dropdown in the main toolbar. - -**NOTE:** The setup wizard can not be run if the web client is hosted separately. - ---- -

-This project is supported by: -
-
-DigitalOcean -   -JetBrains logo -

+Join us on discord https://discord.gg/Ce4PmFcX7Y diff --git a/tests/Jellyfin.MediaEncoding.Tests/Subtitles/AssParserTests.cs b/tests/Jellyfin.MediaEncoding.Tests/Subtitles/AssParserTests.cs index fe0d7fc90..6d90929e1 100644 --- a/tests/Jellyfin.MediaEncoding.Tests/Subtitles/AssParserTests.cs +++ b/tests/Jellyfin.MediaEncoding.Tests/Subtitles/AssParserTests.cs @@ -14,7 +14,7 @@ public void Parse_Valid_Success() { using (var stream = File.OpenRead("Test Data/example.ass")) { - var parsed = new SubtitleEditParser(new NullLogger()).Parse(stream, "ass"); + var parsed = new AssParser(new NullLogger()).Parse(stream, CancellationToken.None); Assert.Single(parsed.TrackEvents); var trackEvent = parsed.TrackEvents[0]; diff --git a/tests/Jellyfin.MediaEncoding.Tests/Subtitles/SrtParserTests.cs b/tests/Jellyfin.MediaEncoding.Tests/Subtitles/SrtParserTests.cs index 2aebee556..a1e941446 100644 --- a/tests/Jellyfin.MediaEncoding.Tests/Subtitles/SrtParserTests.cs +++ b/tests/Jellyfin.MediaEncoding.Tests/Subtitles/SrtParserTests.cs @@ -14,7 +14,7 @@ public void Parse_Valid_Success() { using (var stream = File.OpenRead("Test Data/example.srt")) { - var parsed = new SubtitleEditParser(new NullLogger()).Parse(stream, "srt"); + var parsed = new SrtParser(new NullLogger()).Parse(stream, CancellationToken.None); Assert.Equal(2, parsed.TrackEvents.Count); var trackEvent1 = parsed.TrackEvents[0]; @@ -36,7 +36,7 @@ public void Parse_EmptyNewlineBetweenText_Success() { using (var stream = File.OpenRead("Test Data/example2.srt")) { - var parsed = new SubtitleEditParser(new NullLogger()).Parse(stream, "srt"); + var parsed = new SrtParser(new NullLogger()).Parse(stream, CancellationToken.None); Assert.Equal(2, parsed.TrackEvents.Count); var trackEvent1 = parsed.TrackEvents[0]; diff --git a/tests/Jellyfin.MediaEncoding.Tests/Subtitles/SsaParserTests.cs b/tests/Jellyfin.MediaEncoding.Tests/Subtitles/SsaParserTests.cs index 6abf2d26c..e5451d462 100644 --- a/tests/Jellyfin.MediaEncoding.Tests/Subtitles/SsaParserTests.cs +++ b/tests/Jellyfin.MediaEncoding.Tests/Subtitles/SsaParserTests.cs @@ -12,7 +12,7 @@ namespace Jellyfin.MediaEncoding.Subtitles.Tests { public class SsaParserTests { - private readonly SubtitleEditParser _parser = new SubtitleEditParser(new NullLogger()); + private readonly SsaParser _parser = new SsaParser(new NullLogger()); [Theory] [MemberData(nameof(Parse_MultipleDialogues_TestData))] @@ -20,7 +20,7 @@ public void Parse_MultipleDialogues_Success(string ssa, IReadOnlyList