Port blog posts from old website

This commit is contained in:
MrTimscampi 2021-05-08 06:56:44 +02:00
parent a1c91aaf9b
commit 110bc8f6d1
54 changed files with 1603 additions and 45 deletions

View File

@ -1,11 +0,0 @@
---
slug: hola
title: Hola
author: Gao Wei
author_title: Docusaurus Core Team
author_url: https://github.com/wgao19
author_image_url: https://avatars1.githubusercontent.com/u/2055384?v=4
tags: [hola, docusaurus]
---
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet

View File

@ -1,17 +0,0 @@
---
slug: hello-world
title: Hello
author: Endilie Yacop Sucipto
author_title: Maintainer of Docusaurus
author_url: https://github.com/endiliey
author_image_url: https://avatars1.githubusercontent.com/u/17883920?s=460&v=4
tags: [hello, docusaurus]
---
Welcome to this blog. This blog is created with [**Docusaurus 2 alpha**](https://docusaurus.io/).
<!--truncate-->
This is a test post.
A whole bunch of other information.

View File

@ -1,13 +0,0 @@
---
slug: welcome
title: Welcome
author: Yangshun Tay
author_title: Front End Engineer @ Facebook
author_url: https://github.com/yangshun
author_image_url: https://avatars0.githubusercontent.com/u/1315101?s=400&v=4
tags: [facebook, hello, docusaurus]
---
Blog features are powered by the blog plugin. Simply add files to the `blog` directory. It supports tags as well!
Delete the whole directory if you don't want the blog features. As simple as that!

View File

@ -0,0 +1,18 @@
---
title: Welcome to the New Website!
author: Anthony Lavado
author_url: https://github.com/anthonylavado
author_image_url: https://avatars.githubusercontent.com/u/596194?v=4
tags: [project]
description: Static pages built with Hugo, and more communication.
---
Welcome to our brand new website.
At first glance, it may not look like much has changed - the theme and colours are still the same, and so is our frontpage. What has changed, is what's under the hood. Our website is now built using [Hugo](https://www.gohugo.io), a static-page generator written in Go.
As part of the move, we've decided to introduce this new blog, where you'll be able to hear more about Jellyfin's new releases, future development, and goals. Occasionally, we'll feature guest posts from some of our own contributors.
<!--truncate-->
Thank you for using Jellyfin. We can't wait to share what's next!

View File

@ -0,0 +1,27 @@
---
title: "Jellyfin in 2019"
author: Joshua Boniface
author_url: https://github.com/joshuaboniface
author_image_url: https://avatars.githubusercontent.com/u/4031396?v=4
tags: [project]
description: "Reflections on our first year"
---
It feels hard to believe, but the Jellyfin project is now over a year old. With our official founding somewhere around December 8th 2018, Andrew and I weren't sure exactly what was going to happen. Did we have the resources to make a fork of Emby really happen? Were the doubters right in saying that we wouldn't last a year? It seems that we've proven them, and ourselves, wrong.
<!--truncate-->
What started with just a few people, some forked code, and an idea a little over a year ago has now grown to a thriving community of contributors and users, always ready to help make something better: a truly FLOSS media server, one which refuses to bow to the pressures of commercialization, and that seeks to keep this space free. Without all of you, we wouldn't have gone anywhere at all, and for that you have our eternal thanks!
2019 has been a busy year for the [Core Server project](https://github.com/jellyfin/jellyfin). Starting with our first "real" release of 10.0.0 in early January 2019, we've been through 5 "major" releases and over a dozen hotfix revisions. There have been some significant changes to both the backend and frontend to help make Jellyfin more stable, more performant, and easier to use, with plenty more on the horizon. We've removed tons of cruft, embedded 3rd-party libraries, and dead code, while adding numerous useful features. And we've built in support for numerous platforms, including Debian/Ubuntu, Fedora/CentOS, Windows with both portable and installer versions, MacOS with officially signed DMG images, and most popular of all with over 52 million pulls, Docker. Plugins are growing as well, with over 20 now available - some ports of Emby plugins, some brand-new - and more coming all the time.
For the core server, 2020 looks to be just as exciting: our long-term plans continue to include a full database rewrite, permitting far better performance, backup/restore flexibility, and support for additional database engines, as well as continual overhaul of the WebUI to address usability concerns. [Our Fider feature request center](https://features.jellyfin.org) continues to grow with many well-requested features, and our hope is that the major overhaul work will be finished early this year so we can get on to new features without relying on spaghetti and duct tape to achieve them. If you're interested in helping, please check out our [How To Contribute](https://jellyfin.org/contribute/) page for details.
The client side has been equally exciting. We started 2019 without a single client, Emby having just cut us off from their clients out of spite. Through the dedicated work of a small subteam, 2019 brought us four well-supported clients all on the way to full release: [Android](https://github.com/jellyfin/jellyfin-android) and [Android TV](https://github.com/jellyfin/jellyfin-androidtv) are both in the major App stores (Google Play and Amazon) as well as available as [direct `.apk` downloads](https://repo.jellyfin.org/releases/client), including [Chromecast](https://github.com/jellyfin/jellyfin-chromecast) support, while [Kodi](https://github.com/jellyfin/jellyfin-kodi) was consolidated into a single client and remains well-maintained with constant improvement, including support for Kodi 16-18 with 19 on the way, improved IPv6 support, and support for Unicode. Late last year we also released an [iOS Expo App](https://github.com/jellyfin/jellyfin-expo), which is currently in TestFlight Beta, which will hopefully bring us more support for Apple devices. [Roku](https://github.com/jellyfin/jellyfin-roku), one of our most requested clients, had to be started from scratch, due to issues with the forked code, and continues to improve, though it is still under active development, with video playback mostly working. We also have preliminary support for [WebOS](https://github.com/jellyfin/jellyfin-webos), which still must be side-loaded but generally works. Finally [the Mopidy plugin](https://github.com/jellyfin/mopidy-jellyfin) has been ported and improved extensively, offering proper population of the Mopidy library, multi-library support, and audio-book playback.
Though we admittedly still lack some of the more well-requested but "niche" clients, some of which we may never see, 2020 still looks exciting on the client front. Improvements continue to come in across the entire App ecosystem, and though work on our new React client has been slow, we have high hopes for this to replace most of the disparate clients we have now. Now as always we can use contributors across the board, so if development on any of the platforms is familiar to you, please check out our [How To Contribute](https://jellyfin.org/contribute/) page for details.
I would be remiss to not discuss the Jellyfin community, both [over on Reddit](https://reddit.com/r/jellyfin), [our own forums](https://forum.jellyfin.org), as well as our Matrix chats. Jellyfin wouldn't have gone anywhere without both users to test us out and recommend us, as well as those willing to help their fellow user leaving us free to progress the project. We sincerely appreciate everything you do to help no matter how small.
I wish all of you a happy new year, a happy decade, and many many hours of watching enjoyment on your Jellyfin instances!
Cheers,
Joshua, Project Co-Leader

View File

@ -0,0 +1,32 @@
---
title: "Client Spotlight: MPV Shim"
author: Ian Walton
author_url: https://github.com/iwalton3
author_image_url: https://avatars.githubusercontent.com/u/8078788?v=4
tags: [client spotlight, clients, mpv]
description: Watch all your favorite content without transcoding!
---
Jellyfin MPV Shim is a lightweight cast-only client that allows you to cast videos from Jellyfin to the <a href="https://mpv.io/">MPV Media Player</a>.
<!--truncate-->
It runs in the system tray and stays out of your way until you want to play something. It also has excellent codec support and many configurable options for advanced users.
If you watch a lot of anime, this client is definitely for you. The player has full support for 10-bit HEVC video with subtitles. Additionally, there is a menu option that allows setting subtitles and audio preferences over an entire season of TV at once.
<img src="/static/img/posts/mpv-shim/blender.png" name="Interface" />
To get started on Windows, simply <a href="https://github.com/iwalton3/jellyfin-mpv-shim/releases">download the binary</a> and run it. If you are on Linux, <a href="https://github.com/iwalton3/jellyfin-mpv-shim/blob/master/README.md#linux-installation">follow the instructions here</a>. After you have started the client, enter the URL of your server and the username and password to connect. The client will run in a tray icon, which allows you to access the configuration and view the error logs.
Casting media is easy. Open the Play On menu in the Jellyfin web or mobile clients and select Jellyfin MPV Shim. Then play media normally. Youll be able to control most aspects of playback from the web application or by <a href="https://github.com/iwalton3/jellyfin-mpv-shim#keyboard-shortcuts">using keyboard shortcuts</a>. Most of the options can be accessed using the menu during playback. Press `C` on your computer or use the arrow-based navigation controls in the mobile client when supported.
<img src="/static/img/posts/mpv-shim/menu.png" name="Configuration Menu" />
You can adjust playback settings and preferences in the menu with ease. Use the arrow keys and enter to navigate and escape to go back. The **Auto Set Audio/Subtitles** option allows you to set the subtitles for an entire season at once, instead of having to change the settings each time the episode changes. Use the **Preferences** menu to adjust the default playback settings and remote video quality.
:::note Client Spotlight
This series aims to highlight some of the amazing projects created by our community.
Feel free to send us a message if you can think of a project that could use more love!
:::

View File

@ -0,0 +1,36 @@
---
title: Jellyfin for Kodi Release - v0.5.0
author: Matt Carlton
author_url: https://github.com/mcarlton00
author_image_url: https://avatars.githubusercontent.com/u/17029228?v=4
tags: [release, clients, kodi]
description: Gotta Go Fast
---
Announcing Kodi 19 support, Python 3, and more!
<!--truncate-->
> Please make sure you are either upgrading from version 0.4.1, or restart Kodi after upgrading to 0.5.0. There are some incompatibilities with new libraries that can't be resolved at runtime and require either the previous version or a restart to initialize properly.
## Highlights
- Kodi 19 support
- Significantly faster sync speed
- Less noisy logs
## Overview
Kodi 19 (code named 'Matrix') is right around the corner and we're ready for its arrival. Matrix is currently in a pre-release state and alpha releases are available in Team Kodi's [nightly download repo](https://mirrors.kodi.tv/nightlies/). This is a big release in that Matrix introduces Python 3 support into the Kodi addon ecosystem.
Other exciting news is that we have some significant speed increases within the addon, particularly surrounding the initial library sync. In some cases we're seeing sync times well below half of their previous values. This is largely due to new contributor [druscoe](https://github.com/druscoe), so there's some well deserved shout outs there.
## Release Notes
Full release notes available on [GitHub](https://github.com/jellyfin/jellyfin-kodi/releases/tag/v0.5.0).
## Download Now
If you have the Jellyfin for Kodi addon repository installed and updates enabled, this version will automatically be installed for you.
If you have installed the addon manually, the new zip file is available [here](https://repo.jellyfin.org/releases/client/kodi/plugin.video.jellyfin/plugin.video.jellyfin-0.5.0.zip).

View File

@ -0,0 +1,113 @@
---
title: Jellyfin Release - v10.5.0
author: Julien Machiels
author_url: https://github.com/MrTimscampi
author_image_url: https://avatars.githubusercontent.com/u/19396809?v=4
tags: [release, server]
description: Our biggest release yet
---
import { ImgComparisonSlider } from '@img-comparison-slider/react';
A myriad of improvements, bugfixes, and a look towards the future.
<!--truncate-->
With **over 200 contributions** and **over 500 issues closed**, this is our biggest release yet. We're releasing a bit before the expected Christmas deadline, but our anniversary release packs a lot of new features.
<div className="margin-bottom--md">
<a href="/downloads/" className="button button--primary margin-right--md">Download Jellyfin 10.5.0</a>
<a href="https://github.com/jellyfin/jellyfin/releases/tag/v10.5.0" className="button button--secondary">Read the full release notes</a>
</div>
This post will feature some of the main enhancements available in Jellyfin version 10.5.0. For an exhaustive list of all the changes, you can find a complete list on [GitHub](https://github.com/jellyfin/jellyfin/releases/tag/v10.5.0).
## Web client
This cycle, part of our focus was on improving the look and feel of the web client.
<ImgComparisonSlider className="margin-bottom--md">
<img slot="before" src="/static/img/posts/jellyfin-10-5-0/old-home.jpg" />
<img slot="after" src="/static/img/posts/jellyfin-10-5-0/new-home.jpg" />
</ImgComparisonSlider>
The web client now uses the **Noto Sans** font for all the languages we ship with. This makes for a more consistent experience and ensures that **multilingual libraries look unified**.
Jellyfin 10.5.0 ships with the Latin, Greek, Chinese, Japanese, Korean, Arabic, Cyrillic, Hebrew, Vietnamese and Devanagari versions of the Noto font, optimized for the web.
<ImgComparisonSlider className="margin-bottom--md">
<img slot="before" src="/static/img/posts/jellyfin-10-5-0/old-details.png" />
<img slot="after" src="/static/img/posts/jellyfin-10-5-0/new-details.png" />
</ImgComparisonSlider>
The most noticeable visual change is the **new details page layout**. It puts the artwork of your library front and center while looking more modern and polished.
We have also completely **overhauled SSA/ASS subtitle support**. Through the use of asm.js and Web Assembly, we now provide improved rendering for these formats, fixing some long-standing issues for anime lovers. Note that this feature is still experimental. If you notice lag in the rendering of complex effects, you can enable burn-in by selecting *All complex formats* in *User Settings > Subtitles > Burn subtitles*.
However, most of the new developments in the web client are not immediately visible. We spent a lot of time preparing and cleaning the code for future improvements.
<img data-label="10.5.0" src="/static/img/posts/jellyfin-10-5-0/webos-icons.png" name="" />
A few long-standing issues for WebOS have been fixed as well, bringing us a bit closer to the release of the WebOS app. Among these, icons are now properly working and the client has been reported to work on both WebOS 3 and WebOS 4. We also have plans for the next release that should improve compatibility with earlier WebOS versions and streamline the support of clients using older browser versions as a base. Navigation in the TV layout has also been substantially improved, paving the way for navigation using a remote.
Finally, several performance and responsiveness issues have been addressed. A rogue gamepad input loop is now properly handled, which prevents unnecessary repaintings by the browser and should improve performance. A previously disabled fade-in effect for images has also been enabled, making loading into a new page look smoother. It is now also possible to upload artwork in WEBP format.
## Server
This cycle, our server team ported the code over to .NET Core 3.1. This move makes new features available to our developers, including support for ARM64 for Linux, compatibility with TLS v1.3 and better garbage collection on Docker, allowing for better memory usage when running in a container.
**Support for AMD AMF hardware encoding** is now available on Windows and Linux. We also improved DVD support when added as folders. The metadata provider for TheMovieDB now handles season images. Furthermore, various issues with media scanning, base URLs and DLNA were fixed. **Full hardware acceleration** for Raspberry Pi is also now supported for older models. For Raspeberry Pi 4, hardware-accelerated encoding for H264 is now supported on Raspbian, both using the LinuxServer.io Docker and the repository package.
As part of a project to move the core metadata providers to plugins, MusicBrainz is now a default plugin and allows you to configure the URL of the instance you want to pull data from. This allows you to host an instance of MusicBrainz and sidestep the global rate limiting enforced by the main service.
In addition to all these improvements, more tests have been added on the server-side to help developers track down issues with new and existing code. This ensures a faster development time and helps prevents regressions, which will now be caught earlier through automated testing.
## Documentation
Our documentation team has also been hard at work improving both the user and developer documentation.
Of note recently are the overhauls to the [Networking](https://jellyfin.org/docs/general/networking/index.html) and [Hardware Acceleration](https://jellyfin.org/docs/general/administration/hardware-acceleration.html) sections.
We now provide an extensive [Codec Support](https://jellyfin.org/docs/general/clients/codec-support.html) list and help on [CSS Customization](https://jellyfin.org/docs/general/clients/css-customization.html), with examples of useful CSS customizations to apply to your server via the Administration dashboard.
## Looking towards the future
A lot is happening in the world of Jellyfin recently. Since the release of Jellyfin 10.4.0, we have seen a lot of new contributors joining the team and the speed of development has tremendously accelerated.
With the influx of contributors, we have a few large scale projects for both the server and the web client that should bring a ton of improvements to Jellyfin. More information is already available on [GitHub](https://github.com/jellyfin/) if you want to take part in the discussion or implementation.
We'd like to thank all the contributors to this release for their hard work and dedication to making the best FOSS media server possible.
* [Abbe98](https://github.com/Abbe98/)
* [anthonylavado](https://github.com/anthonylavado/)
* [Artiume](https://github.com/Artiume/)
* [Bond-009](https://github.com/Bond-009/)
* [bugfixin](https://github.com/bugfixin/)
* [cvium](https://github.com/cvium/)
* [dhartung](https://github.com/dhartung/)
* [dinki](https://github.com/dinki/)
* [dkanada](https://github.com/dkanada/)
* [dmitrylyzo](https://github.com/dmitrylyzo/)
* [DrPandemic](https://github.com/DrPandemic/)
* [EraYaN](https://github.com/EraYaN/)
* [ferferga](https://github.com/ferferga/)
* [grafixeyehero](https://github.com/grafixeyehero/)
* [joshuaboniface](https://github.com/joshuaboniface/)
* [JustAMan](https://github.com/JustAMan/)
* [LogicalPhallacy](https://github.com/LogicalPhallacy/)
* [mark-monteiro](https://github.com/mark-monteiro/)
* [MrTimscampi](https://github.com/MrTimscampi/)
* [Narfinger](https://github.com/Narfinger/)
* [Nickbert7](https://github.com/Nickbert7/)
* [nvllsvm](https://github.com/nvllsvm/)
* [nyanmisaka](https://github.com/nyanmisaka/)
* [oddstr13](https://github.com/oddstr13/)
* [ploughpuff](https://github.com/ploughpuff/)
* [redSpoutnik](https://github.com/redSpoutnik/)
* [sparky8251](https://github.com/sparky8251/)
* [thornbill](https://github.com/thornbill/)
* [vitorsemeano](https://github.com/vitorsemeano/)
* [Wunax](https://github.com/Wunax/)
* [YouKnowBlom](https://github.com/YouKnowBlom/)
If you'd like to take part in the development of Jellyfin, most of the contributors are available on [GitHub](https://github.com/jellyfin/) or via [any of the ways on our contact page](/contact/).

View File

@ -0,0 +1,23 @@
---
title: "Jellyfin: Now on Xbox One (UPDATED)"
author: Anthony Lavado
author_url: https://github.com/anthonylavado
author_image_url: https://avatars.githubusercontent.com/u/596194?v=4
tags: [release, clients, xbox]
description: Bet you didn't see this one coming!
---
Due to long standing issues with this current release of the Xbox client beta, and incompatibility with the latest release of Jellyfin, we've made the decision to remove it from the store. We hope to return soon, with an updated client. In the meanwhile, please try using the Edge browser, or Kodi with our plug-ins to watch Jellyfin.
<!--truncate-->
~~Jellyfin is proud to announce our brand new <a href="https://www.microsoft.com/store/apps/9P2DRTG62QF8">Xbox One client beta</a>.~~
Thanks to some very [helpful contributors](https://github.com/jellyfin/jellyfin-uwp/graphs/contributors), Jellyfin is now available for your Xbox One:
<!--<a href="//www.microsoft.com/store/apps/9P2DRTG62QF8?cid=storebadge&ocid=badge"><img src="/images/store-icons/microsoft.svg" alt="View Jellyfin in the Microsoft Store" style="width: 142px; height: 52px;"/></a>-->
To get started, use the icon above, or search the store for "Jellyfin". We also plan on expanding this client to Windows in the near future.
Do you have suggestions or ideas on how to improve the experience? [Let us know](/contact), or visit the project on [GitHub](https://github.com/jellyfin/jellyfin-uwp).
Happy streaming!

View File

@ -0,0 +1,62 @@
---
title: "Client Spotlight: Infuse for tvOS and iOS"
author: Anthony Lavado
author_url: https://github.com/anthonylavado
author_image_url: https://avatars.githubusercontent.com/u/596194?v=4
tags: [client spotlight, clients, infuse]
description: Enjoy your library on Apple TV, iPhone, and iPad
---
Today, [Firecore](https://firecore.com) has launched [Infuse 6.4](https://firecore.com/infuse) for Apple TV, iPhone, and iPad.
This release brings official support for Jellyfin, built right in.
<!--truncate-->
With Infuse, it's easy to connect to with automatic server discovery. Once connected, you can enjoy direct playback (no transcoding required) for almost all formats.
There are way too many features to list them all, but here's a few.
With Infuse, you can:
- Enjoy hardware decoded H.264 and H.265 video
- Direct play of 4K video with HDR
- Direct play of Dolby Vision (single-layer) and Dolby Atmos
- Playback position sync with Jellyfin, and Trakt
- Sync videos for offline playback
- Adjustable playback speed
- PiP and Split View support on iPadOS
When you get Infuse Pro:
- High res audio decoding (Dolby True HD, DTS-HD MA)
- AirPlay and Google Cast support
- Even more format support
---
<a href='https://apps.apple.com/app/id1136220934?mt=8'><img height="77" src="/static/img/posts/infuse/infuse-6-icon.png"/></a> <a style={{ paddingLeft: '20px' }} href='https://apps.apple.com/app/id1136220934?mt=8'><img width="153" alt='Download on the App Store' src='/static/img/store-icons/app-store.svg'/></a>
Infuse is a free download on the [App Store](https://apps.apple.com/app/id1136220934?mt=8).
Infuse Pro can be purchased separately, or through in-app subscription.
---
Here's what our demo library looks like on Apple TV with Infuse 6.4.
_Click a screenshot for a full 2160p view._
<img src="/static/img/posts/infuse/infuse-screenshot-1-thumb.png" name="Main Screen" />
<img src="/static/img/posts/infuse/infuse-screenshot-2-thumb.png" name="Movie View" />
<img src="/static/img/posts/infuse/infuse-screenshot-3-thumb.png" name="Movie Detail View" />
:::note Client Spotlight
This series aims to highlight some of the amazing projects created by our community.
Feel free to send us a message if you can think of a project that could use more love!
:::

View File

@ -0,0 +1,70 @@
---
title: Packaging Updates for 10.6.0
author: Joshua Boniface
author_url: https://github.com/joshuaboniface
author_image_url: https://avatars.githubusercontent.com/u/4031396?v=4
tags: [packaging, server]
description: "Some backend packaging changes are here: what you should know"
---
Packaging and building binaries for releases and testing has long been an issue for us. From fighting with duct-tape-and-coat-hanger scripts, to testing breaking changes, to massaging official releases, how we were doing things for the last year-and-a-half needed some improvements.
Luckily, today they are all completed. In this post, I'll detail the changes as well as what the entail for our users.
For a brief TL;DR: for most users of our stable releases, not much will change, and you will upgrade to 10.6.0 as you always have. For anyone using nightlies for testing, advanced setups, or who are just curious - read on!
<!--truncate-->
### Split Builds
The first main component of the packaging changes is split builds. Previously, we were relying on some serious hackery in order to build both the Web UI (https://github.com/jellyfin/jellyfin-web) and Server (https://github.com/jellyfin/jellyfin) and combine them into one package. Ultimately, with the sheer number of changes in both repositories and speed at which updates happen, along with our eventual goal to decouple the two from each other for releases, this sort of solution had reached its limits. This is perhaps best exemplified by the mostly-unseen work I had to do to get 10.5.4 and 10.5.5 to build at all.
With split packages, the two repositories are now built completely independently for all platforms. If you build the `jellyfin-web` repository, you get out a Docker image, `.deb` packages, `.rpm` packages, or a `.tar.gz` archive that just contains the Web UI. Similarly, if you build the `jellyfin` repository, you get out the various Docker, `.deb`, `.rpm`, `.tar.gz`, and `.zip` archives you know and love.
The main difference is the naming - the `jellyfin-web` repository binaries are named, well, `jellyfin-web`, and the `jellyfin` repository binaries are named `jellyfin-server`. So, to use Debian as an example, where there was once `jellyfin`, there is now `jellyfin-web` and `jellyfin-server`. But don't worry, `jellyfin` is not gone - we'll get to that shortly.
### Azure Pipelines builds
Our previous build infrastructure consisted of a veritable spaghetti factory of Bash, Python, and Docker scripts that were executed on our build server, a DigitalOcean droplet. For the most part, it worked, but the process was very fragile, opaque (I'm not even sure *I* understand how it all worked all the time, and I wrote it all!), and resource-intensive.
As we've moved more and more functions to Azure for testing, verification, linting, etc. in the various repositories, it became obvious that Azure Pipelines had a lot of flexibility, and would be able to perform nearly all of our build steps for us. This eliminated at least 2/3 of the build server, and gives us another cool option - unstable builds, which I'll touch on shortly.
The Azure Pipelines build handles the actual building of all the archives for both repositories mentioned in the previous section, uploads the binary artifacts to the build server, and then kicks off a single script to handle the last 1/3 of the process, making things much clearer, more obvious, and with results visible to everyone in our Azure project page.
### Metapackages and Metaimages
I previously mentioned that the package which used to be called `jellyfin` is now called `jellyfin-server`, and does not contain the Web UI. So, how do you get it all? And how will upgrades be seamless? The answer is metapackages, metaarchives, and metaimages! These new components can be found in [this repository page](https://github.com/jellyfin/jellyfin-metapackages), specifically the Docker images which will now be the source of truth for those configurations. I'll outline how each platform behaves below.
For Docker, the Azure pipelines split builds create docker images called `jellyfin/jellyfin-server` and `jellyfin/jellyfin-web`. On their own they're not too useful, but exist to enable the next step. When an Azure build finishes and has uploaded these images, a script is kicked off on our build server which builds the `jellyfin/jellyfin` "metaimage", which will take the two separate images, and combine them into a single Docker image along with all the components to run them, like `jellyfin-ffmpeg`, then push the resulting image. The end result is a single image, `jellyfin/jellyfin`, like there has always been, but the builds are done independently rather than relying on `git clone`/archive downloads inside the build steps and other shenanigans.
For Debian and Ubuntu, the Azure pipelines split builds create separate `.deb` packages for each component. Unlike Docker, these are fully usable on their own, and installing Jellyfin in 10.6.0+ can be done with `apt install jellyfin-server jellyfin-web` if one wishes. The metapackage is a separate `.deb`, called `jellyfin`, who's only function is to have dependencies on these two component packages. Thus, installing `jellyfin` will automatically install `jellyfin-server` and `jellyfin-web`, along with the other required dependencies from each. This is how upgrades will be seamless from previous versions: upgrading from the old `jellyfin` to the new `jellyfin` will automatically pull in the two new subpackages and remove the old one, with no interruptions.
For Fedora and CentOS, the setup is similar to Debian/Ubuntu, with the only difference being the metapackage is a component of the `jellyfin-server` repository and is thus only rebuilt when that repository is. However, since we do not provide a "proper" repository for these packages like we do for Debian/Ubuntu, the impact should be quite low, and will be nonexistent for stable releases.
For Windows installers and MacOS `.app` packages, the process remains a little more complicated and a WIP, but those will continue to work on release.
For the remaining platforms, including the archive packages for Windows, MacOS, Linux, and .NET portable, the process takes the two separate `.tar.gz` / `.zip` archives from the build process, and combines them into a single `jellyfin` archive of the same type, which puts the two component parts in their respective places. Thus, like all the others mentioned above, the change should be invisible to users by downloading the "combined" version of the archives.
### Unstable builds
One of the cool things that this new setup enables is "unstable" builds. For quite a while now, we've been providing (when not broken) "nightly" builds, which as their name implies are build every night if there were merged PRs from the previous day. However, these had a number of drawbacks. First, they broke a lot; second, on a busy day it would be possible for there to be up to a dozen separate PRs that made up the nightly changeset; third, they could often be totally messed up in terms of contents, for instance if the unsplit build grabbed the wrong version of Web.
The new split builds, Azure builds, and metapackages/metaimages instead let us do something far superior: build "unstable" releases for *every merged PR*. We don't have to worry about resource usage (Azure provides this), disk space, or other aspects of the build process. We can know immediately if something breaks. And most importantly, it lets anyone test our master branch in a very clear way, knowing *exactly* what version of the repository you are using and what the last merged PR was if something goes wrong.
Unstable builds are versioned based on the Azure build ID, which is in the format "[date].[id]", for example "20200620.12" for the 12th build on June 20th 2020. Thus this version string will tell you exactly which Azure build generated the binary, and thus which PR in which repository triggered it. For those binaries with changelogs (`.deb` and `.rpm` packages only for now), the changelog data includes the PR ID explicitly as well.
### Using Unstable builds
Using unstable builds is a bit different than the previous nightlies. For those, the packages/images were named `jellyfin-nightly` or `jellyfin:nightly` (for Docker) and were stored in the same repositories. This has now changed somewhat, and I'll detail the changes to each platform below. Note that, at least until 10.6.0 is released, we will continue to build `nightly` images as we always have, after which they will be turned off in favour of `unstable` builds exclusively, so if you like to live on the bleeding edge, please review this section in detail and make the required changes as soon as you can.
For Docker, the new unstable builds are available with the `unstable` tag, e.g. `jellyfin/jellyfin:unstable`, or at a specific version tag, for instance `jellyfin/jellyfin:20200620.12-unstable`. Following the main `unstable` tag will ensure you can always grab the latest unstable build, while the versioned tags allow you to pull specific builds for testing or debugging.
For Debian and Ubuntu, where the unstable images are stored has changed. As mentioned, previously they were part of the `main` section of the repository with the alternate name `jellyfin-nightly`, and this is no longer the case for unstable. Instead, a separate repository "component" called `unstable` has been created to house the unstable builds, and they are not renamed. To enable this extra component, add a line to your `/etc/apt/sources.list.d/jellyfin.list` like the following, which is identical to the existing line except with `main` replaced by `unstable`: `deb [arch=amd64] https://repo.jellyfin.org/debian buster unstable`. Because of how the versioning works, once you enable this additional source, you will always get the `unstable` packages with their "very high" version numbers over the stable releases, so to disable unstable builds, you must remove this extra line, run `apt update`, remove the old package(s), then install the stable version.
For all other releases, since the source was always files downloaded from [our repository site](https://repo.jellyfin.org/releases), not much will change - instead of downloading files from the `nightly/` folder of your platform, download from the `unstable/` folder. Note that these folders will, because of the split builds, contain separate subfolders for `server`, `web`, and `combined`; generally you will want `combined`. You can then use these archives as you always have.
### Conclusions
Thank you for reading this description of our build changes. We continue to test these extensively to work out any bugs, but if you have questions or feedback, please drop us a message on Matrix!
We hope to see you very soon for 10.6.0, and many future releases with this new format!

View File

@ -0,0 +1,104 @@
---
title: Plugin Repositories
author: dkanada
author_url: https://github.com/dkanada
author_image_url: https://avatars.githubusercontent.com/u/21353219?v=4
tags: [plugins, server]
description: Install Plugins from Anywhere!
---
There have been several changes to plugins for the new release.
Here's a quick post going over the biggest updates for developers and users alike.
<!--truncate-->
The most noticable change for everyone is that third party plugin repositories are now available!
You can access the current list at Dashboard -> Plugins -> Repositories, and items can be added or removed as desired.
Even the official repository can be removed if you'd prefer to avoid external calls to our server.
# Manifest
For developers, the only required change is a JSON manifest at *any* location with versions that point to binary releases at *any* location.
We don't require any specific method for hosting these files, as that would go against the ideals of the project.
The official repository uses nginx for the manifest and GitHub Releases for the binaries, but you could potentially host the manifest on GitHub as well.
Here's an example manifest with all the properties.
Please note that the GUID must be unique (both in the manifest and the plugin itself) if you want to avoid conflicts with other plugins.
```json
[
{
"category": "Metadata",
"guid": "a4df60c5-6ab4-412a-8f79-2cab93fb2bc5",
"name": "Anime",
"description": "This plugin supports several different metadata providers and options for organizing your collection.",
"owner": "jellyfin",
"overview": "Manage Your Anime in Jellyfin",
"versions": [
{
"checksum": "ad6db5175f4732308b5dd166f79a1c2d",
"changelog": "bug fixes and improvements",
"targetAbi": "10.6.0.0",
"sourceUrl": "https://repo.jellyfin.org/releases/other/whats-this-plugin.zip.gif",
"timestamp": "2020-03-27 06:02:58",
"version": "1.0.3.0"
}
]
}
]
```
The official repository manifest for <a href="https://repo.jellyfin.org/releases/plugin/manifest-stable.json">stable plugins</a> can be used for more examples.
You can also find the <a href="https://repo.jellyfin.org/releases/plugin/manifest.json">deprecated manifest</a> on the same domain for the old format.
However, all new plugin updates (on the official repository) will go to the new manifest, so older verions of Jellyfin won't receive plugin updates.
Plugins do have <a href="https://jellyfin.org/docs/plugin-api/MediaBrowser.Model.Updates.html">official documentation</a> on our DocFX instance.
Please be aware that our documentation is still a work in progress, since a lot of the C# code still has very little information for tools like this.
Things are improving thanks to the diligent server team though, who have been slowly adding information throughout the codebase.
# Tools
One excellent tool that might help with repository management is <a href="https://github.com/oddstr13/jellyfin-plugin-repository-manager">jellyfin-plugin-repository-manager</a> by Oddstr13, a frequent contributor.
He did mention that his tool works much better with nginx than GitHub releases, but feel free to check it out!
Another useful tool might be the <a href="https://github.com/jellyfin/jellyfin-build">jellyfin-build</a> repository, which used to be the method used for updates on the official repository.
We'll probably be migrating to the repository manager linked above though, since most of the other build systems have moved to Azure.
# Code
There are always a few changes to the ABI you might want to know about if you maintain a plugin.
I'll include the most important ones for 10.6.0 here to hopefully reduce any issues with the update.
The first batch comes from the HTML for settings on the web client, which has been going through an overhaul lately.
One of the long term goals we have is deprecating jQuery entirely, since it's not 2008 anymore and better tools have come along.
That does mean plugin pages will have to migrate off it at some point, but we haven't made the full transition yet, don't worry.
Although jQuery will stick around a bit longer, we did remove two custom scripts in the web source that...extended the functionality a bit.
There was one for <a href="https://github.com/jellyfin/jellyfin-web/blob/release-10.5.z/src/legacy/selectmenu.js">select menus</a> and yet another for <a href="https://github.com/jellyfin/jellyfin-web/blob/release-10.5.z/src/legacy/fnchecked.js">checkbox</a> elements.
I can only assume the goal was compatibility with older browsers or clients at the time, but we've been pushing extremely hard to modernize the web client.
That means avoiding abandoned libraries, ancient JavaScript practices, and definitely custom extensions for dependencies we don't even want in the code.
The easiest fix for this change is to migrate from jQuery to vanilla JavaScript for checkboxes and select menus in the HTML source.
There were also several changes to the C# ABI that might affect your plugin.
The most troublesome is probably the ILogger tweaks, which were made to improve the server logs by appending the class name to every line.
You'll also find quite a few changes caused by the new database migration (Jellyfin.Data is the new namespace for these objects) and a few unrelated items.
```sh
IExternalID.Name -> IExternalID.ProviderName
MediaBrowser.Controller.Entities.User -> Jellyfin.Data.Entities.User
MetadataProviders -> MetadataProvider
CompressionMethod -> CompressionMethods
RequestContentBytes = request -> RequestContent = Encoding.UTF8.GetString(request)
User.Name -> User.Username
item.GetDisplayExtras() -> item.GetExtras(BaseItem.DisplayExtraTypes)
user.RootFolder -> libraryManager.GetUserRootFolder()
```
# Future
Third party repositories are the first step in a larger plan to vastly increase plugin usage within the codebase.
They will allow anyone to maintain their own plugin and push updates as quickly as they want, without having to deal with a centralized system.
It also gives users the power to reduce their reliance on an internet connection by allowing all repositories to be removed at will.
We understand some of these changes might be annoying to update within your plugin, but hopefully that will also see an improvement very soon.
The next goal (now that more than one repository can be used at the same time) will be an unstable repository for plugins.
This will fix the long-standing request for better plugin support on the unstable version, which has been a blocker for many users.
It will also have the side effect of requiring an unstable NuGet repository for the C# ABI, thus helping third party plugin developers test their plugins against any changes to the ABI before a server update has landed.
If you develop a plugin (or client) and would like to be included in our mailing list for third party developers, please contact us through Matrix or send an email to get the details.
The main goal here is excellent support for plugins and unofficial clients, so if you have any suggestions definitely contact us on one of our public forums.
Hopefully, the C# ABI will stabilize over time and huge changes will become more infrequent so we can focus on making plugins as great as possible!

View File

@ -0,0 +1,197 @@
---
title: Jellyfin Release - v10.6.0
author: Julien Machiels
author_url: https://github.com/MrTimscampi
author_image_url: https://avatars.githubusercontent.com/u/19396809?v=4
tags: [release, server]
description: Party together while social distancing
---
import { ImgComparisonSlider } from '@img-comparison-slider/react';
After months of work, here comes another behemoth of a release, this time with over 30 major improvements and tons of fixes.
<!--truncate-->
<div className="margin-bottom--md">
<a href="/downloads/" className="button button--primary margin-right--md">Download Jellyfin 10.6.0</a>
<a href="https://github.com/jellyfin/jellyfin/releases/tag/v10.6.0" className="button button--secondary">Read the full release notes</a>
</div>
At **more than 500 pull requests** merged between the server and the web client, Jellyfin 10.6.0 brings an incredible number of new features, improvements and bug fixes. It's a huge release and we have a lot to cover, so let's get to it!
## SyncPlay
Other services have recently launched various ways to view your content together with friends. With the current global situation, it makes a lot of sense, and Jellyfin isn't lagging behind.
We're proud to announce Jellyfin 10.6's headline feature: **SyncPlay**.
SyncPlay allows you to create rooms that other users or clients can join in order to share a common viewing experience. There is no limit on the number of users in a room and you are free to join the same room with the same user from multiple clients as well.
Thanks to first-time contributor [OancaAndrei](https://github.com/OancaAndrei), who submitted pull requests to both the server and the web client ([jf#2733](https://github.com/jellyfin/jellyfin/pull/2733), [jf-web#1011](https://github.com/jellyfin/jellyfin-web/pull/1011)) in order to lay out the foundations for this, you can now watch movies together with friends and family, from the comfort of your respective homes.
The feature is expected to be improved in future versions of Jellyfin, but has already been used by multiple users during the development cycle, with a delay between clients of only a couple of milliseconds.
## Migration to Entity Framework Core
It's been on our plate for a while, but thanks to new team member [barronpm](https://github.com/barronpm), we can finally say that the rewrite of our database model is progressing at a steady pace!
Previously, Jellyfin used a combination of SQLite databases (yes, multiple ones), XML files and C# spaghetti to perform database operations. Information was split in multiple places, sometimes even duplicated and generally filtered in C# instead of using the database engine's faster processing.
Over the course of this cycle, [barronpm](https://github.com/barronpm) has been deciphering and untangling this mess, and managed to successfully migrate the ActivityDB ([jf#2970](https://github.com/jellyfin/jellyfin/pull/2970)) and the UserDB ([jf3148](https://github.com/jellyfin/jellyfin/pull/3148)) to EF Core.
While there is still a ways to go, EF Core should bring faster database queries, support for multiple database engines, cleaner code, and significantly reduced memory usage. Currently, there is still a bridge to make the link between the new EF Core databases and the existing code, which will be cleaned up down the line.
Part of the improved memory usage is due to our current inherited custom ORM caching everything in memory to make up for its slowness. For large databases, this could result in hundreds of megabytes of memory lost to caching. With EF Core, however, we leave the heavy lifting to the database engine, leading to better response times and less memory usage overall.
Your databases will be automatically migrated when you first launch Jellyfin 10.6. While the migration process has been well tested over the past few months, issues may arise during the migration process. To prevent any data loss, please **backup your existing data files** before starting the migration process.
## A more modern web client
Our web client has long suffered of a massive amount of technical debt, due to the project we forked from only providing minified versions of the source and using antiquated web technologies. Some of these old technologies have, until recently, prevented us from being able to use modern JavaScript tooling, which would allow us to significantly clean the source.
Thankfully, this is now behind us, as [MrTimscampi](https://github.com/MrTimscampi) worked on improving the way we build the web client by using Gulp to perform various tasks necessary for building our current code structure with modern tools. ([jf-web#862](https://github.com/jellyfin/jellyfin-web/pull/862)). This allows us to use bleeding edge JavaScript thanks to Babel, but also simplifies greatly our support for legacy clients (Most notably early WebOS and Tizen versions).
Among the benefits of this move to Gulp for building the client, we have started moving away from [RequireJS](https://requirejs.org/) and towards using standard [EcmaScript Modules](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules), thanks to [Camc314](https://github.com/Camc314), [cromefire](https://github.com/cromefire/), [Delgan](https://github.com/delgan), [dkanada](https://github.com/dkanada/), [grafixeyehero](https://github.com/grafixeyehero/), [MrTimscampi](https://github.com/MrTimscampi), and [sarab97](https://github.com/sarab97/).
This massive change, once it is complete, will allow us to simplify the web client build process, which will in turn allow us to start our migration to [Vue](https://vuejs.org/) and significantly clean up our code. This should also bring some noticeable performance improvements to the web client down the line, as we tackle technical debt and remove deprecated practices and libraries from the code.
## Server performance, bug fixes and better networking
Our resident C# performance wizard, [Bond-009](https://github.com/Bond-009) continues his quest to rid the server source of warnings and generally improve server performance, fixing multiple bugs in the process.
[mark-monteiro](https://github.com/mark-monteiro) worked on multiple fixes for 10.6, including reworking the network settings accessible through the administration dashboard ([jf#2774](https://github.com/jellyfin/jellyfin/pull/2774), [jf-web#1140](https://github.com/jellyfin/jellyfin-web/pull/1140)).
Team member [nyanmisaka](https://github.com/nyanmisaka), with some help from [artiume](https://github.com/artiume/), brings a number of improvements to transcoding ([jf#2809](https://github.com/jellyfin/jellyfin/pull/2809), [jf-web#1046](https://github.com/jellyfin/jellyfin-web/pull/1046), [jf#2821](https://github.com/jellyfin/jellyfin/pull/2821), [jf#2715](https://github.com/jellyfin/jellyfin/pull/2715)), with format toggles, options for toggling transcoding for HEVC and 10-bit VP9 videos off for older GPUs, providing support for the VP8/VP9 QSV and NVDEC decoders in FFmpeg 4.3, better support for UTF-16 subtitles and a host of other improvements.
Further changes to the server include fixes for collection metadata issues ([jf#3117](https://github.com/jellyfin/jellyfin/pull/3117)), improvements to the metadata providers ([jf#3071](https://github.com/jellyfin/jellyfin/pull/3071), [jf#3056](https://github.com/jellyfin/jellyfin/pull/3056), [jf#3289](https://github.com/jellyfin/jellyfin/pull/3289)), and more core providers moved to plugins ([jf#3208](https://github.com/jellyfin/jellyfin/pull/3208)).
## More web client improvements
[Itegulov](https://github.com/itegulov) and [dkanada](https://github.com/dkanada/) have improved support for ebooks by adding an EPUB reader based on [epub.js](https://github.com/futurepress/epub.js/) ([jf-web#1263](https://github.com/jellyfin/jellyfin-web/pull/1263)). Reader support for more formats is in progress for future versions, including CBZ/CBR and PDF.
As we used the new 10.5 details screen over the last few months, we noticed some improvements we could make to the experience. Team member [MrTimscampi](https://github.com/MrTimscampi), along with input from the rest of the web team and some of our users, did a second pass on that screen ([jf-web#949](https://github.com/jellyfin/jellyfin-web/pull/949), [jf-web#1206](https://github.com/jellyfin/jellyfin-web/pull/1206)), tightening the design and cleaning some visual issues along the way. [Delgan](https://github.com/jellyfin/jellyfin-web/pull/1406) put in the final touches to the page by avoiding a jump in the content when rendering the track selectors on the page ([jf-web#1406](https://github.com/jellyfin/jellyfin-web/pull/1406))
<ImgComparisonSlider className="margin-bottom--md">
<img slot="before" src="/static/img/posts/jellyfin-10-6-0/details-10-5.png" />
<img slot="after" src="/static/img/posts/jellyfin-10-6-0/details-10-6.png" />
</ImgComparisonSlider>
Team member [ferferga](https://github.com/ferferga) and contributor [samuel9554](https://github.com/samuel9554) have been working on redesigning our music experience. For 10.6, they overhauled our mobile music player interface and made significant changes to the mini player and the remote player UI ([jf-web#1056](https://github.com/jellyfin/jellyfin-web/pull/1056), [jf-web#1430](https://github.com/jellyfin/jellyfin-web/pull/1430)).
<ImgComparisonSlider className="margin-bottom--md">
<img slot="before" src="/static/img/posts/jellyfin-10-6-0/player-10-5.png" />
<img slot="after" src="/static/img/posts/jellyfin-10-6-0/player-10-6.png" />
</ImgComparisonSlider>
[MrTimscampi](https://github.com/MrTimscampi) also reworked the image loading system ([jf-web#1065](https://github.com/jellyfin/jellyfin-web/pull/1065)), fixing some visual issues and improving memory usage by unloading out of view images. Along with this improvement, [ferferga](https://github.com/ferferga), [GranPC](https://github.com/GranPC), [JustAMan](https://github.com/JustAMan) and [Bond-009](https://github.com/Bond-009) have implemented [Blurhash](https://blurha.sh/) placeholder support on both the server and the web client, which brings further visual refinement to the user interface.
[JustAMan](https://github.com/JustAMan) went back over our new SSA/ASS subtitle rendering system and significantly improved performance for subtitles with heavy effects ([jf-web#1144](https://github.com/jellyfin/jellyfin-web/pull/1144), [jf-web#1095](https://github.com/jellyfin/jellyfin-web/pull/1095), [jf-web#1048](https://github.com/jellyfin/jellyfin-web/pull/1048), [jf-web#1005](https://github.com/jellyfin/jellyfin-web/pull/1005)). While we still consider the feature experimental, it should now be able to render most subtitles accurately and with correct performance.
Other improvements to the web client include a rewritten image viewer ([jf-web#967](https://github.com/jellyfin/jellyfin-web/pull/967)), a configuration option for the number of items per page in libraries ([jf-web#983](https://github.com/jellyfin/jellyfin-web/pull/983)), a toggle for the nightly version of the Chromecast client ([jf-web#1242](https://github.com/jellyfin/jellyfin-web/pull/1242)), and support for multiple plugin repositories ([jf-web#1393](https://github.com/jellyfin/jellyfin-web/pull/1393), [jf#3244](https://github.com/jellyfin/jellyfin/pull/3244)).
## Patreons and Github Sponsors
With the increased amount of activity on the project, we would like to give a signal boost to some ways to support the people working daily on Jellyfin.
We want to stress that, while some of our contributors individually accept financial donations, Jellyfin and its features will **never** be hidden behind a paywall. Supporting the developers financially is entirely voluntary and won't give you any exclusive access to features or support, nor will it change the priority of your feature requests or issues.
[anthonylavado](https://github.com/anthonylavado), our wonderful PR and developer relation person, accepts donations through [Github Sponsors](https://github.com/sponsors/anthonylavado).
[barronpm](https://github.com/barronpm), whose main work is on the server portion of Jellyfin and who has been spearheading the migration to EF Core has recently opened [a Patreon page](https://www.patreon.com/barronpm).
[dkanada](https://github.com/dkanada/), whose work spreads from server to web client, accepts donations through [Github Sponsors](https://github.com/sponsors/dkanada)
[ferferga](https://github.com/ferferga), web client contributor, localization aficionado and all-around awesome person accepts donations through [Github Sponsors](https://github.com/sponsors/ferferga).
[nielsvanvelzen](https://github.com/nielsvanvelzen), who has been working hard on the Android TV client, can be supported on [Github Sponsors](https://github.com/sponsors/nielsvanvelzen).
[MrTimscampi](https://github.com/MrTimscampi), whose main work has been cleaning up and modernizing the web client, also recently opened [a Patreon page](https://www.patreon.com/mrtimscampi).
[oddstr13](https://github.com/oddstr13), one of the developers of Jellyfin for Kodi also accepts donations on [Github Sponsors](https://github.com/sponsors/oddstr13).
[thornbill](https://github.com/thornbill) who handles the iOS and Android clients, and also contributes to the Android TV client, can be supported on [Github Sponsors](https://github.com/sponsors/thornbill)
## Contributors
As an final note, we would like to thank all the contributors who worked on making Jellyfin 10.6 a reality:
* [adavier](https://github.com/adavier/)
* [aled](https://github.com/aled/)
* [alset333](https://github.com/alset333/)
* [anthonylavado](https://github.com/anthonylavado/)
* [Artiume](https://github.com/Artiume/)
* [balu92](https://github.com/balu92/)
* [BaronGreenback](https://github.com/BaronGreenback/)
* [barronpm](https://github.com/barronpm/)
* [bendardenne](https://github.com/bendardenne/)
* [Bond-009](https://github.com/Bond-009)
* [Brissot](https://github.com/Brissot/)
* [Camc314](https://github.com/Camc314/)
* [ConfusedPolarBear](https://github.com/ConfusedPolarBear/)
* [crobibero](https://github.com/crobibero/)
* [cromefire](https://github.com/cromefire/)
* [cvium](https://github.com/cvium/)
* [dafo90](https://github.com/dafo90/)
* [danieladov](https://github.com/danieladov/)
* [Delgan](https://github.com/Delgan/)
* [dkanada](https://github.com/dkanada/)
* [dmitrylyzo](https://github.com/dmitrylyzo/)
* [dtparr](https://github.com/dtparr/)
* [EraYaN](https://github.com/EraYaN/)
* [ferferga](https://github.com/ferferga/)
* [fhriley](https://github.com/fhriley/)
* [grafixeyehero](https://github.com/grafixeyehero/)
* [GranPC](https://github.com/GranPC/)
* [h1nk](https://github.com/h1nk/)
* [hauntingEcho](https://github.com/hauntingEcho/)
* [itegulov](https://github.com/itegulov/)
* [iwalton3](https://github.com/iwalton3/)
* [jairbubbles](https://github.com/jairbubbles/)
* [joshuaboniface](https://github.com/joshuaboniface/)
* [JustAMan](https://github.com/JustAMan/)
* [kesslern](https://github.com/kesslern/)
* [KGT1](https://github.com/KGT1/)
* [KristupasSavickas](https://github.com/KristupasSavickas/)
* [KucharczykL](https://github.com/KucharczykL/)
* [lfoust](https://github.com/lfoust/)
* [lyonzy](https://github.com/lyonzy/)
* [macr](https://github.com/macr/)
* [mark-monteiro](https://github.com/mark-monteiro)
* [masterkoppa](https://github.com/masterkoppa/)
* [mijofa](https://github.com/mijofa/)
* [MrTimscampi](https://github.com/MrTimscampi/)
* [Nazar78](https://github.com/Nazar78/)
* [neilsb](https://github.com/neilsb/)
* [Nickbert7](https://github.com/Nickbert7/)
* [nielsvanvelzen](https://github.com/nielsvanvelzen/)
* [nyanmisaka](https://github.com/nyanmisaka/)
* [OancaAndrei](https://github.com/OancaAndrei/)
* [oddstr13](https://github.com/oddstr13)
* [ox0spy](https://github.com/ox0spy/)
* [Polpetta](https://github.com/Polpetta/)
* [PrplHaz4](https://github.com/PrplHaz4/)
* [puschie286](https://github.com/puschie286/)
* [pusta](https://github.com/pusta/)
* [randrey](https://github.com/randrey/)
* [redSpoutnik](https://github.com/redSpoutnik/)
* [rexbron](https://github.com/rexbron/)
* [rigtorp](https://github.com/rigtorp/)
* [rotvel](https://github.com/rotvel/)
* [samuel9554](https://github.com/samuel9554/)
* [sarab97](https://github.com/sarab97/)
* [Shawmon](https://github.com/Shawmon/)
* [shayaantx](https://github.com/shayaantx/)
* [sparky8251](https://github.com/sparky8251/)
* [Stampede10343](https://github.com/Stampede10343/)
* [telans](https://github.com/telans/)
* [ThibaultNocchi](https://github.com/ThibaultNocchi/)
* [thornbill](https://github.com/thornbill/)
* [twinkybot](https://github.com/twinkybot/)
* [Ullmie02](https://github.com/Ullmie02/)
* [viaregio](https://github.com/viaregio/)
* [villagra](https://github.com/villagra/)
* [whooo](https://github.com/whooo/)
* [xumix](https://github.com/xumix/)
* [YouKnowBlom](https://github.com/YouKnowBlom/)
* [ZadenRB](https://github.com/ZadenRB/)

View File

@ -0,0 +1,38 @@
---
title: "Client Spotlight: Videotape"
author: Jose Maria Villagra
author_url: https://github.com/villagra
author_image_url: https://avatars.githubusercontent.com/u/1038513?v=4
tags: [client spotlight, clients, xbox, windows]
description: Bringing smooth playback to the Xbox One & Windows 10 with Jellyfin
---
Videotape is a free lightweight video player for both Windows 10 & Xbox. Their new 3.0 version now supports Jellyfin!
<!--truncate-->
Videotape is a native UWP application with a strong focus on design and usability.
- Direct play almost all files, both from Jellyfin and other local files
- Overlay and always on top modes
- Adjustable playback speed
Download it now from the Microsoft store!
<a href="//www.microsoft.com/store/apps/9NLVH2LL4P1Z?cid=storebadge&ocid=badge"><img src="/static/img/store-icons/microsoft.svg" alt="View VideoTape in the Microsoft Store" style={{ width: '142px', height: '52px' }}/></a>
Here's what Jellyfin looks like on Windows, with Videotape 3.
<img src="/static/img/posts/videotape/detailview.png" name="Detail View on Windows 10" />
Here's what it looks like on the Xbox One.
<img src="/static/img/posts/videotape/detailxbox.png" name="Detail View on Xbox One" />
:::note Client Spotlight
This series aims to highlight some of the amazing projects created by our community.
Feel free to send us a message if you can think of a project that could use more love!
:::

View File

@ -0,0 +1,54 @@
---
title: Android Developers Rejoice
author: dkanada
author_url: https://github.com/dkanada
author_image_url: https://avatars.githubusercontent.com/u/21353219?v=4
tags: [release, clients, android]
description: We have a brand new web wrapper for Android sans Cordova!
---
This will be a net benefit for users and developers alike!
<!--truncate-->
Everyone will enjoy the native video player spearheaded by [Stampede10343](https://github.com/Stampede10343) and [vitorsemeano](https://github.com/vitorsemeano) over the course of several months.
[Maxr1998](https://github.com/Maxr1998) valiantly ported the Cordova portions to Kotlin (and a bit of Java) which means Android developers will feel right at home with the new codebase!
### Migration
The new release will be a drop-in replacement for the deprecated Cordova client, meaning you can just update from GitHub, Google Play, or Amazon App Store as you would have previously.
One minor issue is that you'll have to add your server and credentials again since we couldn't pull the information from Cordova.
Local user settings such as the theme will also be reset after the update.
Azure has also been updated so the releases will be automatically built, and Weblate now points to the new codebase.
Older versions will remain on [our repository](https://repo.jellyfin.org) for the time being but don't expect them to stay forever, so if you have some reason to stash the older APKs download them soon!
:::note
This client has a new set of translations, so if you speak more than one language head on over to Weblate to help out the new client!
:::
### ExoPlayer
The key feature for this release is ExoPlayer, so we've reserved a whole section for news regarding the player and its functionality.
It's currently disabled by default since there may be small issues, but it works quite well in our experience.
The main features missing at the moment are bitrate limiting and SyncPlay, but they should get added eventually.
There is a new section in the user settings for the native client from which you can enable ExoPlayer, among other options.
A toggle for the notification dismissal was also added for customization.
Of course, using ExoPlayer means support for more codecs during video playback as well!
H265 should be working without transcodes, and several other problematic codecs are now much less troublesome with the new update.
:::note
The included device profile still needs some tweaking to actually mark every codec that the phone supports as supported to the server. You can follow the progress on this at [jellyfin/jellyfin-android#28](https://github.com/jellyfin/jellyfin-android/issues/28).
:::
### Future
The goal is to use a mobile-first interface for ExoPlayer so we can focus more on desktop for the normal web player.
Bigger, easier clickable buttons and double tap to seek are some of the changes setting the new interface apart from the HTML5 video player.
As usual, since this is a volunteer project we don't actually have set milestones, so if you want something done, the quickest method is to add it yourself!
Head over to [Matrix](https://matrix.to/#/+jellyfin:matrix.org) or Freenode and get in touch with the Android developers if you'd like to talk about adding a new feature.
Our [GitHub](https://github.com/jellyfin/jellyfin-android) is also an excellent place to discuss long term changes for the new client now that a more modern build process is in place.

View File

@ -0,0 +1,77 @@
---
title: Android v2.1.0 - Jellyfin in your car!
author: 'Niels van Velzen'
author_url: https://github.com/nielsvanvelzen
author_image_url: https://avatars.githubusercontent.com/u/2305178?v=4
tags: [release, clients, android]
description: Listen to your music while driving with the new Android update
---
Jellyfin for Android version 2.1 is here with support for Android Auto.
<!--truncate-->
A new version of the Android app: version 2.1 has just been released! This update contains some quality of life improvements, some bugfixes and new features.
It's been only a few weeks since 2.0 but we couldn't wait to bring these new exiting changes to you. Let's start with the most awesome feature.
## Android Auto
Starting with this update we now support playing music in cars. This change was contributed by [@Spacetech](https://github.com/Spacetech) and we are excited to release it. Right now it supports browsing your music library in multiple categories: latest, albums, artists, songs and genres. It allows shuffling your albums and shows thumbnails when available.
<video controls loop autoplay muted playsinline class="inline justify" height="500">
<source src="/static/img/posts/android-2-1-0/android-auto.webm" type="video/webm" />
</video>
:::info
Since we do not have offline-support at the moment all music playback needs an active network connection to work. Be aware this may cause additional charges in your mobile plan.
:::
## Connectivity issues
Some users reported issues when connecting to their server. We've made some improvements to fix those problems:
- When your server uses an outdated version a warning is shown.
- If the web UI fails to load we now show a proper error allowing you to change the server address.
- Users with self-signed certificates should be able to use the app again.
- And lastly, when your device name includes special characters they are now removed to fix the "endless loading" issue.
## Playback improvements
The native video player (ExoPlayer) now supports zooming using gestures so you can remove the black bars from the video. We made some changes to which audio codecs are supported to prevent unnecessary transcoding. We also made some big changes to the structure of the app to fix an issue where you weren't able to return to the app after leaving Picture-in-Picture mode.
There is a new option in the settings to select which external player to use. The listed players should also report playback status back to Jellyfin to track what you watch and allow the app to resume playback. Issues with subtitles (especially external subtitles) should now be less common.
## F-Droid
We have added the required metadata for F-Droid to our repository. We are currently working with the F-Droid team to get the app in their repository - we will post an additional announcement when this is ready.
## Release Notes
Full release notes available on [GitHub](https://github.com/jellyfin/jellyfin-android/releases/tag/v2.1.0).
## Download Now
<a href="https://play.google.com/store/apps/details?id=org.jellyfin.mobile" class="margin-right--md">
<img width="153" alt="Jellyfin on Google Play" src="/static/img/store-icons/google-play.png" />
</a>
<a href="https://www.amazon.com/gp/product/B081RFTTQ9">
<img width="153" alt="Jellyfin on Amazon App Store" src="/static/img/store-icons/amazon.png" />
</a>
Direct downloads are always available from [our repository](https://repo.jellyfin.org/releases/client/android/).
## Contributors
We are grateful to all contributors this release:
- [@Maxr1998](https://github.com/Maxr1998) - [Sponsor](https://github.com/sponsors/Maxr1998)
- [@nielsvanvelzen](https://github.com/nielsvanvelzen) - [Sponsor](https://github.com/sponsors/nielsvanvelzen)
- [@vitorsemeano](https://github.com/vitorsemeano)
- [@ferferga](https://github.com/ferferga) - [Sponsor](https://github.com/sponsors/ferferga)
- [@CarlosOlivo](https://github.com/CarlosOlivo)
- [@Spacetech](https://github.com/Spacetech)
- [@h1dden-da3m0n](https://github.com/h1dden-da3m0n)
- [@IzzySoft](https://github.com/IzzySoft)

View File

@ -0,0 +1,62 @@
---
title: "Please refresh your Jellyfin Apt key on Debian/Ubuntu"
author: Joshua Boniface
author_url: https://github.com/joshuaboniface
author_image_url: https://avatars.githubusercontent.com/u/4031396?v=4
tags: [packaging]
description: "Our old key is expiring December 15th, read on to find out how to update"
---
Our GPG key for signing our Debian and Ubuntu repositories (`https://repo.jellyfin.org/debian` and `https://repo.jellyfin.org/ubuntu`) is set to expire next month.
<!--truncate-->
Unfortunately this was an oversight when we first set up this repo, and we never provided any convenient way to update this. As a remedy, we've removed the expiry on the key and put a new version on the repo. This brings us into line with numerous other 3rd-party Debian repositories, such as the Microsoft .NET and Docker repositories which also use an expiry-less key, and should avoid any such issues again, barring a need to rotate it. This does however require manually refreshing the key on your system.
Doing this is as easy as re-running the command from the install docs; it will overwrite the old key with the new one:
```
wget -O- https://repo.jellyfin.org/jellyfin_team.gpg.key | sudo apt-key add -
```
You can verify this worked by checking the `apt-key` output like so; this is a good practice anyways to verify that the key has not been altered, as its signatures and fingerprint should all match:
```
$ apt-key list | grep -C2 jellyfin # Notice the expires: field
Warning: apt-key output should not be parsed (stdout is not a terminal)
pub rsa3072 2018-12-16 [SC] [expires: 2020-12-15]
4918 AABC 486C A052 358D 778D 4902 3CD0 1DE2 1A7B
uid [ unknown] Jellyfin Team <team@jellyfin.org>
sub rsa3072 2018-12-16 [E] [expires: 2020-12-15]
$ wget -O- https://repo.jellyfin.org/jellyfin_team.gpg.key | sudo apt-key add -
[...]
$ apt-key list | grep -C2 jellyfin # Notice the expires: is now gone
Warning: apt-key output should not be parsed (stdout is not a terminal)
pub rsa3072 2018-12-16 [SC]
4918 AABC 486C A052 358D 778D 4902 3CD0 1DE2 1A7B
uid [ unknown] Jellyfin Team <team@jellyfin.org>
sub rsa3072 2018-12-16 [E]
```
If you find this didn't work, try removing the key first with this command, then re-add it again:
```
sudo apt-key remove 1DE21A7B
```
We've also published the key to the Ubuntu keyserver as a backup, just in case, or if you prefer this method. Our docs will retain the direct-file method however. You can use this command to obtain the key directly from the Ubuntu keyserver:
```
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv 1DE21A7B
```
**Please ensure you refresh the key before December 15th, or you will find that `apt update` no longer works!**
GitHub Issue for reference: https://github.com/jellyfin/jellyfin/issues/4528
Reddit thread for reference: https://www.reddit.com/r/jellyfin/comments/jz6u9o/debian_ubuntu_repo_users_our_key_is_expiring/
Thanks,
Joshua

View File

@ -0,0 +1,34 @@
---
title: Android app now on F-Droid
author: 'Niels van Velzen'
author_url: https://github.com/nielsvanvelzen
author_image_url: https://avatars.githubusercontent.com/u/2305178?v=4
tags: [release, clients, android]
description: 'Available to download right now!'
---
We're happy to announce the immediate availability of the Android mobile app on the F-Droid store. The F-Droid version does not contain any proprietary libraries and builds are fully reproducible.
<!--truncate-->
## Missing features
Unfortunately, the library required for casting support is proprietary, meaning that it's not available under a free license and Google doesn't publish the source code. Because of that, we had to remove it in the F-Droid version. Fortunately, the remote control feature still works.
Additionally, the Android Auto integration does not work because Google does not allow apps to integrate with it when the app was not installed from the Google Play store.
## Download Now
<a href="https://play.google.com/store/apps/details?id=org.jellyfin.mobile" class="margin-right--md">
<img width="153" alt="Jellyfin on Google Play" src="/static/img/store-icons/google-play.png" />
</a>
<a href="https://www.amazon.com/gp/product/B081RFTTQ9" class="margin-right--md">
<img width="153" alt="Jellyfin on Amazon App Store" src="/static/img/store-icons/amazon.png" />
</a>
<a href="https://f-droid.org/en/packages/org.jellyfin.mobile/">
<img width="153" alt="Jellyfin on F-Droid" src="/static/img/store-icons/fdroid.png" />
</a>
Direct downloads are always available from [our repository](https://repo.jellyfin.org/releases/client/android/).

View File

@ -0,0 +1,392 @@
---
title: "The Jellyfin CDN: Mirrorbits for the masses"
author: Joshua Boniface
author_url: https://github.com/joshuaboniface
author_image_url: https://avatars.githubusercontent.com/u/4031396?v=4
tags: [project, infrastructure]
description: "How Jellyfin distributes binary packages"
---
For many projects, distributing binary assets is easy: put the files on GitHub and you're done. It's not something many think about. But at Jellyfin, we needed something more robust, something able to handle our needs more elegantly than GitHub or a basic web server could. And both for those interested, and for those supporting other similar projects, I'd like to share how we do it.
<!--truncate-->
## Prelude - Pre-10.6.0
Before our 10.6.0 release, we had a fairly simple repository setup: everything would build on a VPS, running Debian, called `build1`, in response to a GitHub web-hook. This server, located on Digital Ocean in the Toronto zone, housed both the build process as well as our main repository, served directly via NGiNX.
But this release was the first where we noticed a problem. Jellyfin is a global project, and while I'm personally located in Ontario, Canada, the very vast majority of our users are not. And users, especially users in Europe and Asia, were having trouble downloading our releases. The main complaint was abysmally slow download speeds, and occasionally even full-on timeouts. We had to come up with a better solution.
As a DIYer at heart, and leading a project built by and for DIYers, I wasn't content to simply throw CloudFlare in front of the repo - my concerns with that provider notwithstanding. I wanted something we could control, and I went looking for a solution - how to effectively create a CDN for file downloads.
## Enter Mirrorbits
Luckily, I wasn't alone. Many years before, another FLOSS project had encountered the same problem. VideoLAN, creators of the fantastic VLC Media Player, had the same issue of distributing files. So one of their talented developers created a solution: Mirrorbits.
[Mirrorbits](https://github.com/etix/mirrorbits) is a Go program with a single goal: provide a way to distribute requests from a single central repository to multiple geo-diverse repositories, based on the client's GeoIP information, handling availability and freshness seamlessly. It seemed to fit the bill exactly.
But there was a problem: documentation on how to actually run Mirrorbits was sparse, so it took quite a bit of trial-and-error to determine how to use it. I hope the following will help avoid this trouble for anyone else.
## File Layout
The first thing to consider is the layout of the files. In Jellyfin's case, our repository is large and sprawling, constituting many different components including the server, clients, plugins, and various secondary files. Mirrorbits requires everything to be housed under one directory, and we needed a way to synchronize this whole directory easily. We also had a problem of our "archives", old stable releases that we did not need or want synchronized to all of our mirror servers wasting space.
The solution I came up with was the following directory structure:
```
/srv/repository
/mirror
/releases
/client
/server
/plugin
etc.
/debian
/dists
/pool
/ubuntu
/dists
/pool
/archive
etc.
/releases --symlink--> /mirror/releases
/debian --symlink--> /mirror/debian
etc.
```
In effect, everything is under a `/mirror` directory, with external symlinks to provide the root links we wanted.
## Additional VPSes and Synchronization
The next step after crafting a usable file layout was to create some additional VPSes and determine how to synchronize the files.
Since our origin server is in Toronto, I wanted to ensure we had wide geographic coverage. as well as a dedicated CDN for the same region as the origin server, just in case it got overloaded. Thus, I created 4 additional VPSes:
* `tor1.mirror.jellyfin.org`: Toronto, Ontario, Canada for North/South America East
* `sfo1.mirror.jellyfin.org`: San Francisco, California, USA for North/South America West
* `fra1.mirror.jellyfin.org`: Frankfurt, Germany (not France as commonly assumed!) for Europe and Africa
* `sgp1.mirror.jellyfin.org`: Singapore for Asia and Pacific
One worry when first setting up these 4 VPSes was that they would not be enough, but so far, through another major release and several minor releases, we've had the complaints about download speed completely stop, so they must be working. In future, as Digital Ocean expands, we'd also be able to add other locations as well, for instance Bangalore, India, Africa, and perhaps additional Europe and South America instances.
With the VPSes created, I then looked into file synchronization, and there was only one program on my mind: `rsync`. But while most users know `rsync` for it's `scp`-replacement functionality over SSH, I wanted something more robust without the need for handling SSH keys, and able to be extended further in the future, perhaps to untrusted (and untrusting) 3rd-party mirrors.
I thus opted to use the `rsync` daemon mode. Listening on port 873, it's able to do everything `rsync`-over-SSH can do, only without encryption overhead or requiring SSH/shell authentication.
I first prepared the the local `/etc/rsyncd.conf` on the origin server (`build1`). By default, the Debian `rsync` package does not install the daemon service unless this file exists, but after adding it the daemon can be started.
To handle the aforementioned "archives", I split the repository into two "components": one with the archives, and one without. This would allow a given mirror to pull either the entire archive, or just the current stable repositories. And once we started offering the "unstable" builds that can be generated many dozens of times per day, I opted to include them in the "archive" component as well.
Here is our configuration:
```
# /etc/rsyncd.conf
[mirror]
path = /srv/repository/mirror
comment = Jellyfin mirror (stable only)
exclude = *unstable* *archive*
[mirror-full]
path = /srv/repository/mirror
comment = Jellyfin mirror (all)
```
In many cases, it would be prudent to secure this, but since we wanted to open this up to anyone, I left the `rsync` endpoint completely exposed. Thus, if you want to host a local Jellyfin mirror - you can. Simply clone this rsync target and you'll have a full copy of the Jellyfin mirror!
On the mirror servers, we still needed to get the content however. Ultimately, I decided that every "official" mirror copying the *full* content (including archives and unstable builds) was more prudent, so all of them synchronize the `mirror-full` source.
Each node thus has a simple cron job, set to run every 15 minutes, that downloads an updated copy of the repository from the origin:
```
# /etc/cron.d/mirror-sync
12,27,42,57 * * * * root rsync -au --delete rsync://build1.jellyfin.org/mirror-full/ /srv/repository/mirror/
```
The slightly odd times were chosen specifically - the goal for 3rd parties, if and when we officially support them, would be to synchronize every X minutes on even intervals, e.g. at `00`, `30`, etc., from these "official" mirrors, instead of from build1 directly. This therefore ensures they would always be up-to-date before that time comes around, ensuring no additional delays for 3rd party mirrors. We don't officially support this *yet*, but if our traffic continues to grow, we will probably expand to 3rd parties as well as additional Digital Ocean locations.
The `rsync` command should create the destination directory automatically, but to be prudent, I ensured it was created manually first. Thus, we now have 5 servers with exactly the same content, with the mirrors synchronizing from the origin every 15 minutes.
## Web server Configuration
From the very beginning we have used NGiNX as the web server. The reasons are simple: maximum configuration flexibility, and performance. Apache has its place, but we didn't need its additional features, and early on budget was tight. I've been so satisfied with it, I haven't even considered a change.
On the mirrors, the configuration is dead-simple. Only a single "site" is configured, providing full access to the repository directory. SSL is provided by Let's Encrypt.
```
# /etc/nginx/sites-enabled/jellyfin-mirror (from fra1.mirror.jellyfin.org)
server {
listen [::]:80 default_server ipv6only=on;
listen 80 default_server;
listen [::]:443 ssl ipv6only=on;
listen 443 ssl;
ssl_certificate /etc/letsencrypt/live/fra1.mirror.jellyfin.org/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/fra1.mirror.jellyfin.org/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
server_name fra1.mirror.jellyfin.org _;
root /srv/repository;
index index.php index.html index.htm;
access_log /var/log/nginx/access.log;
aio threads;
directio 1M;
output_buffers 3 1M;
sendfile on;
sendfile_max_chunk 0;
autoindex on;
location ~ [^/]\.php(/|$) {
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
fastcgi_param HTTP_PROXY "";
fastcgi_pass unix:/run/php/php7.3-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
```
During testing, we did notice one thing that might be of use to other admins. We were finding that performance, when many requests for large files came in at once, would drop significantly. I ended up tracing the problem to the I/O stack within NGiNX, which appeared to be a bottleneck. I was able to find some documentation about this problem, and thus have set the `aio threads`, `directio`, `output_buffers`, and `sendfile` options above. These ensure NGiNX will use direct I/O for any file larger than 1M, and provide 3 output buffers with a maximum chunk size of 0, increasing performance under load.
On the origin, the NGiNX configuration is much more complicated. Because Mirrorbits will only distribute the actual large files themselves, I need to handle any pre-file redirection first on the origin. Thus clients are directed to the right file location, and the Mirrorbits directs *that* request to the mirrors.
```
# /etc/nginx/sites-enabled/jellyfin-origin (on build1.jellyfin.org)
server {
listen 80 default_server proxy_protocol;
listen [::]:80 default_server proxy_protocol;
server_name repo.jellyfin.org build.jellyfin.org repo1.jellyfin.org build1.jellyfin.org _;
access_log /var/log/nginx/access.log proxy;
aio threads;
directio 1M;
output_buffers 3 1M;
sendfile on;
sendfile_max_chunk 0;
autoindex on;
root /srv/repository/mirror;
index index.php index.html index.htm index.nginx-debian.html;
location / {
autoindex off;
}
#
# Kodi Repository redirection
#
location ^~ /releases/client/kodi/py2 {
index index.html index.php;
autoindex on;
}
location ^~ /releases/client/kodi/py3 {
index index.html index.php;
autoindex on;
}
location ^~ /releases/client/kodi {
# Kodi 20
if ($http_user_agent ~* "(Kodi.*/20.*)") {
rewrite ^/releases/client/kodi/(.*)$ /releases/client/kodi/py3/$1 last;
}
# Kodi 19
if ($http_user_agent ~* "(Kodi.*/19.*)") {
rewrite ^/releases/client/kodi/(.*)$ /releases/client/kodi/py3/$1 last;
}
# Kodi 18 and older
if ($http_user_agent ~* "(Kodi.*)") {
rewrite ^/releases/client/kodi/(.*)$ /releases/client/kodi/py2/$1 last;
}
index index.html index.php;
autoindex on;
}
#
# Main repository
#
# Main release directories
location /releases {
autoindex on;
}
# Main archive directories (not forwarded to Mirrorbits)
location ^~ /archive {
try_files $uri $uri/ =404;
autoindex on;
}
# Mirrorbits fallback
location ^~ /master {
try_files $uri $uri/ =404;
autoindex on;
}
# Mirrorbits forwards for large file types
location ~ ^/(?<fwd_path>.*)(?<fwd_file>\.apk|\.buildinfo|\.bz|\.changes|\.db|\.deb|\.dmg|\.dsc|\.exe|\.gz|\.md5|\.lzma|\.rpm|\.sha256sum|\.xml|\.xz|\.zip|\.css|\.ttf|\.woff2|\.json)$ {
proxy_pass http://127.0.0.1:8080;
proxy_buffering off;
}
location ~ ^/(?<fwd_path>.*)(/mirrorlist)$ {
proxy_pass http://127.0.0.1:8080/$fwd_path?mirrorlist;
proxy_buffering off;
}
location ~ ^/(?<fwd_path>.*)(/mirrorstats)$ {
proxy_pass http://127.0.0.1:8080/$fwd_path?mirrorstats;
proxy_buffering off;
}
location /mirrorstats {
proxy_pass http://127.0.0.1:8080/?mirrorstats;
proxy_buffering off;
}
#
# PHP handling
#
location ~ \.php$ {
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
fastcgi_param HTTP_PROXY "";
fastcgi_pass unix:/run/php/php7.3-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
```
Some of the configuration here is worthy of describing in detail.
The Kodi selector is used due to the Kodi backend transition from Python 2 to Python 3. Thus, some versions require assets for Python 2, and newer versions for Python 3. This selector operates based on the sent user agent of the client, deciding which version of Kodi they are using, and thus directing them to the right location.
The main locations are `/archive`, `/releases`, and `/master`. The first contains archives and is not forwarded on to the Mirrorbits process (despite the files being synced above) due to the `try_files` directive. The second is the main repository directory, and the third is a duplicate location that is used for fallback and also does not redirect to Mirrorbits.
Next is the main Mirrorbits handler. The forwarding is based off the file extension of the requested file. Thus, when loading, e.g. the PHP index pages, the requests are not forwarded; only requests for the listed file types are forwarded on to the Mirrorbits process to be distributed to mirrors.
The next 3 options are for Mirrorbits status pages, which provide information on the currently available mirrors. For any file (e.g. https://repo.jellyfin.org/releases/server/debian/stable/meta/jellyfin_10.7.2-1_all.deb), one can append the `/mirrorlist` or `/mirrorinfo` locations to show information about the available mirrors. Try it yourself: https://repo.jellyfin.org/releases/server/debian/stable/meta/jellyfin_10.7.2-1_all.deb/mirrorlist. Finally the `/mirrorstats` page, whether on a file or at the root of the domain (https://repo.jellyfin.org/mirrorstats) shows the current status of the mirrors in general, including if any are offline.
All together, these NGiNX configs provide the foundation for Mirrorbits to work, and this was the part that actually took the longest. Thanks to [@PalinuroSec](https://github.com/PalinuroSec) on GitHub for his [fantastic example gist](https://gist.github.com/PalinuroSec/f0bfb815240573ab1b0b58f3c76620d4).
## Mirrorbits: The Workhorse
Installing Mirrorbits is quite straightforward: I simply downloaded the latest binary release (`0.5.1`) from the Mirrorbits repository, installed the `mirrorbits` binary to `/usr/local/bin`, the sample configuration to `/etc/mirrorbits.conf`, and the templates to `/usr/local/share/mirrorbits`. Unfortunately, Mirrorbits development seems to have stalled since 2018, including documentation. [I opened an issue](https://github.com/etix/mirrorbits/issues/105) during my troubleshooting that is still unanswered, which is unfortunate, and I hope this blog post will be able to resolve that issue.
The basic configuration of Mirrorbits is quite simple. Most of the configuration options are explained well in the sample configuration file, and it was simply a matter of tuning them to our needs. Here is our configuration stripped of comments/explanations:
```
# /etc/mirrorbits.conf (on build1.jellyfin.org)
Repository: /srv/repository/mirror
Templates: /usr/local/share/mirrorbits/
LogDir: /var/log/mirrorbits
GeoipDatabasePath: /usr/local/share/GeoIP/
OutputMode: redirect
Gzip: false
ListenAddress: localhost:8080
RPCListenAddress: localhost:3390
RedisAddress: 127.0.0.1:6379
RedisDB: 0
TraceFileLocation: /mirrorsync
RepositoryScanInterval: 5
Hashes:
SHA256: On
ConcurrentSync: 5
ScanInterval: 30
CheckInterval: 1
Fallbacks:
- URL: https://repo.jellyfin.org/master/
CountryCode: ca
ContinentCode: na
```
A few options are worth mentioning as they differ from the obvious defaults.
`Repository` points towards the local repository path, the exact file(s) that are synchronized with `rsync` above.
`GeoipDatabasePath` is a path to a local copy of the GeoIP database; this will be discussed later.
`OutputMode` is set to `redirect` to give clients an HTTP 302 redirect to the file path. There are several options here, but the 302 seemed like the most robust, being well-supported by most HTTP-speaking programs and preventing caching of the response.
`TraceFileLocation` points to a file which is used to judge the "freshness" of the mirrors. It should be a file which guarantees that the remote copies of the repository are in sync with the local instance, and must be under the `Repository` location.
`Hashes` provides several options, but we use SHA256 hashing for simplicity and to match our own provided hashes.
`RedisAddress` points to a local Redis instance that Mirrorbits uses to handle state.
`ConcurrentSync`, `RepositoryScanInterval`, `ScanInterval`, and `CheckInterval` are times in minutes that Mirrorbits *should* be checking and synchronizing itself, but I've found these to be unreliable; I used a cron task to do these tasks manually instead.
Finally, `Fallbacks` provides a list of fallback mirrors. As mentioned above, the `/master` path provides the exact same content as `/releases`, only without being forwarded back to Mirrorbits and creating a loop. Without this fallback, if all mirrors are unavailable for any given file, either due to its newness or due to mirror failures, clients would not be able to download files at all. The fallback ensures there is still at least one source - the origin - that is not normally used, but can be just in case.
The next step was creating a SystemD service for Mirrorbits. The process requires some special options for reloads and stopping, so these are included here. Note also that I run Mirrorbits as `www-data`, the same user as NGiNX itself:
```
# /etc/systemd/system/mirorrbits.service
[Unit]
Description=Mirrorbits redirector
Documentation=https://github.com/etix/mirrorbits
After=network.target
[Service]
Type=notify
DynamicUser=yes
LogsDirectory=mirrorbits
RuntimeDirectory=mirrorbits
User=www-data
PIDFile=/run/mirrorbits/mirrorbits.pid
ExecStart=/usr/local/bin/mirrorbits daemon -p /run/mirrorbits/mirrorbits.pid -debug
ExecReload=/bin/kill -HUP $MAINPID
ExecStop=-/bin/kill -QUIT $MAINPID
TimeoutStopSec=5
KillMode=mixed
Restart=on-failure
[Install]
WantedBy=multi-user.target
```
Finally, I added some cron jobs to ensure that the `TraceFileLocation` is updated regularly, and that the mirror is scanned and refreshed regularly - the things that Mirrorbits itself didn't seem to be handling properly. The trace file is always updated 1 minute before the sync happens, while the mirror scan happens 1 minute after, to give the sync time to complete. The local repository is refreshed every minute to catch any new files as quickly as possible.
```
# /etc/cron.d/mirror-sync
11,26,41,56 * * * * root /usr/bin/date +\%s | /usr/bin/tee /srv/repository/mirror/mirrorsync &>/dev/null
13,28,42,58 * * * * root /usr/local/bin/mirrorbits scan -all
* * * * * root /usr/local/bin/mirrorbits refresh
```
## Adding Mirrors to Mirrorbits
Once all the setup was completed and Mirrorbits running, I added the mirrors to the Mirrorbits system. This is a straightforward process using the Mirrorbits binary:
```
mirrorbits add -http https://fra1.mirror.jellyfin.org -rsync rsync://fra1.mirror.jellyfin.org/mirror fra1
mirrorbits scan --enable fra1
mirrorbits refresh
```
Once scanned, enabled, and refreshed, the mirror became active and and visible in the `/mirrorstats` output or on the CLI, ready to serve requests.
```
joshua@build1.jellyfin.org ~ $ mirrorbits list
Identifier STATE SINCE
fra1 up (Mon, 12 Apr 2021 07:15:29 UTC)
sgp1 up (Mon, 12 Apr 2021 06:51:03 UTC)
tor1 up (Sun, 11 Apr 2021 21:48:48 UTC)
sfo1 up (Sun, 11 Apr 2021 17:43:27 UTC)
```
## GeoIP
One complication of using Mirrorbits is requiring a GeoIP database. It specifically requires the `GeoLite2` `mmdb` format to operate correctly. Unfortunately, this is no longer something that is provided freely. You must obtain this yourself, or find an alternative; I would prefer to use a freely available database, but I have yet to be able to find one that works with Mirrorbits. If you know of one, please let me know!
This database is extracted to the `GeoipDatabasePath` location and is loaded by Mirrorbits at runtime, providing the GeoIP information it then uses to direct clients to the nearest mirror server.
## Conclusion
All together, we hope this setup allows us to continue to scale our downloads for our users across the world. And I hope this post will help another admin of a small project who needs to distribute their downloads across many geo-diverse servers. Good luck!

View File

@ -0,0 +1,34 @@
---
title: A Note About Privacy and Expo for iOS
author: Anthony Lavado
author_url: https://github.com/anthonylavado
author_image_url: https://avatars.githubusercontent.com/u/596194?v=4
tags: [project]
description: Providing transparency to the community
---
When it comes to Jellyfin, we guarantee that there is no involuntary tracking, from the server to the mobile apps. This still remains true, even with today's update to the Apple App Store.
<!--truncate-->
In developing the Jellyfin Mobile app for iOS, we use a Javascript framework known as [Expo](https://expo.io). This framework is an integrated way of using [React Native](https://reactnative.dev) to create mobile apps. For a variety of technical reasons, this has been the best way for us to deliver an iOS app, even with its current restrictions.
Starting with an update in December 2020, Apple has required all developers to submit Privacy Information with any new app, or any update to an app. There is an article covering these "privacy badges" available on Apple's website: "[HT211970 - About privacy information on the App Store...](https://support.apple.com/en-ca/HT211970)". As of our last Jellyfin Mobile update, we believed we were in the clear here - the Jellyfin app does not contain any code to track you or report any data. We declared this in our update information, and received the "Data Not Collected" badge.
However, we learned that Expo has an issue that prevents this from being true. In February, we were contacted by Apple, and received a notice that our badge was incorrect, and needs to be updated. We inquired into this further with Expo, in their forums: "[Mail from App Store Connect about Facebook App Events](https://forums.expo.io/t/mail-from-app-store-connect-about-facebook-app-events/48927)". When we use Expo to build the app (their "managed" workflow), their compiler automatically includes base code for a variety of different items, which includes code that can be used to provide analytics and tracking information. Even though we don't use any of these functions, this code is included in the final app binary, so we are now forced to declare that app can access the Device Identifier.
## I want to stress again: **We do not track any user activity or collect any data.**
You can verify this by reviewing the code base here on GitHub: "[jellyfin/jellyfin-expo](https://github.com/jellyfin/jellyfin-expo)". Expo's current build process includes code that _could_ be used for tracking, but it is never activated by our code, and we do not use it at all. Because this code is ultimately in the app, we have to update the badge on the App Store listing. As Expo explains on their [publishing details page](https://docs.expo.io/distribution/app-stores/#ios-specific-guidelines):
>Note: No data is sent to Branch, Facebook, Segment, or Amplitude from your app unless you explicitly do so using the APIs.
In the [forum thread](https://forums.expo.io/t/mail-from-app-store-connect-about-facebook-app-events/48927), Expo has committed to a future update allowing their automated build service to only include the code modules that you actively use, which would allow us to return to the "Data Not Collected" badge. In an effort to help improve the app and add more features, we are looking to "eject" from Expo in the future, which means we can completely control the build process by ourselves.
---
Thank you for using Jellyfin and supporting us this far. Our iOS app is largely developed only by one contributor, [@thornbill](https://github.com/thornbill), who gives generously of his spare time to develop the app and make it better all the time. He, along with a few of our [contributors](https://github.com/orgs/jellyfin/people) have donation pages setup either through GitHub Sponsors, or other sites like LiberaPay, Patreon and more. If you'd like to support any of them, please see their profiles for more information. If you'd like to support Jellyfin as a whole (infrastructure and equipment costs only), you can visit our public ledger on [OpenCollective](https://opencollective.com/jellyfin). We're pretty well covered for now, so consider donating to contributors first.
Stay tuned for future posts talking about app updates, how we are committed to protecting privacy with Jellyfin, and on our contributor community, including how you can support them and development.
Best,
Anthony

34
blog/2021-04-18-jmp.mdx Normal file
View File

@ -0,0 +1,34 @@
---
title: Introducing Jellyfin Media Player
author: Ian Walton
author_url: https://github.com/iwalton3
author_image_url: https://avatars.githubusercontent.com/u/8078788?v=4
tags: [release, clients, desktop]
description: A new user friendly MPV-based desktop client
---
Jellyfin Media Player is a new Jellyfin client option intended to offer a more user-friendly experience. It takes the user interface from jellyfin-web, including the playback interface, and combines it with the extensive codec support from MPV.
<!--truncate-->
<img src="/static/img/posts/jmp/player.png" name="Player" />
You can [download the client on GitHub](https://github.com/jellyfin/jellyfin-media-player/releases). It is also available on [FlatHub](https://flathub.org/apps/details/com.github.iwalton3.jellyfin-media-player) and the [AUR](https://aur.archlinux.org/packages/jellyfin-media-player/).
## Extensive Feature Set
<img src="/static/img/posts/jmp/config.png" name="Configuration Dialog" />
Building on the open source foundation of Plex Media Player, this client has support for selecting audio devices and configuring audio passthrough. It also supports changing the refresh rate of your display to match the video content. You can control the client with some remote controls, game controllers, and media keys through jellyfin-webs TV display mode, in addition to remote control through the Jellyfin mobile apps. While testing the client it was known to be controllable with a PS3 controller in TV mode.
Since the media player is built on MPV, the mpv.conf file may be used to install scripts and shaders, as well as for tweaking the playback characteristics to the users liking. The software is also known to work with SVP with some tweaking of configuration files.
## Music Support
<img src="/static/img/posts/jmp/music.png" name="Music Playback" />
Jellyfin Media Player can also natively play music in addition to videos. Being built on jellyfin-web and implementing player support as plugins, all features of the web client are available as usual, including server management. The client can connect to and switch between multiple separate servers.
## Extensive Cross-Platform Support
Through the help from several community contributions, Jellyfin Media Player now builds for Windows, macOS, and Linux. All release builds are automated through GitHub Actions. Linux users will be happy to know that Debian, Ubuntu, Flatpak, and AUR packages are available. Contributors are already improving the softwares foundation and have gotten it working on Wayland as well.

View File

@ -0,0 +1,53 @@
---
title: New Android TV Release - v0.11.0
author: 'Niels van Velzen'
author_url: https://github.com/nielsvanvelzen
author_image_url: https://avatars.githubusercontent.com/u/2305178?v=4
tags: [release, clients, android]
subtitle: Improved Video Playback That Goes up to 11
---
Thank you for using Jellyfin! This is a major update for the Android TV client.
<!--truncate-->
:::caution
We have added crash reporting. Read the notes below for more information.
:::
## Highlights
- Upgraded ExoPlayer to version 2
This means video playback should be a lot smoother now!
- New home screen
The newly made home screen now looks more or less the same as the webclient. It will display the sections you have chosen under your "Home" preferences.
*Note: changing sections is only available in the web version for now*
- Integration with "Next Up" section on Android TV devices
## Crash Reporting
Providing logs on Android TV devices can be challenging for users as it requires Android developer tools. Issues can be challenging to replicate for developers and crash logs help a lot with this.
We don't want to force users to report their logs to a third-party and therefore we won't report anything by default. When a crash occured the app will show a dialog and ask to report the logs.
All crash reports are retained for 30 days and can only be reviewed by a small group of developers inside the Android TV team.
More information can be found in the [issue](https://github.com/jellyfin/jellyfin-androidtv/issues/193) about this change.
## Release Notes
Full release notes available on [GitHub](https://github.com/jellyfin/jellyfin-androidtv/releases/tag/v0.11.0).
## Download Now
<a href='https://play.google.com/store/apps/details?id=org.jellyfin.androidtv&utm_source=blog&pcampaignid=pcampaignidMKT-Other-global-all-co-prtnr-py-PartBadge-Mar2515-1' class="margin-right--md">
<img width="153" alt='Get it on Google Play' src='/static/img/store-icons/google-play.png'/>
</a>
<a href='https://www.amazon.com/gp/product/B07TX7Z725/ref=jellyfin_for_fire_tv'>
<img width="153" alt='Available at Amazon App Store' src='/static/img/store-icons/amazon.png'/>
</a>
Direct downloads are always available from [our repository](https://repo.jellyfin.org/releases/client/androidtv/).

View File

@ -113,13 +113,10 @@ module.exports = {
sidebarPath: require.resolve('./sidebars.js'),
// Please change this to your repo.
editUrl:
'https://github.com/facebook/docusaurus/edit/master/website/',
'https://github.com/jellyfin/jellyfin.org/edit/master/',
},
blog: {
showReadingTime: true,
// Please change this to your repo.
editUrl:
'https://github.com/facebook/docusaurus/edit/master/website/blog/',
},
theme: {
customCss: require.resolve('./src/css/custom.css'),

13
package-lock.json generated
View File

@ -1781,6 +1781,14 @@
"prop-types": "^15.7.2"
}
},
"@img-comparison-slider/react": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/@img-comparison-slider/react/-/react-3.0.4.tgz",
"integrity": "sha512-aNDYLp6rs8PjewVfjzvgDjmnGm09kHRaZTInIJ3DTVkTLm3Qo1xdH8WTrMLerZ+CR7Crp/4LpmT1chXkuzqQJw==",
"requires": {
"img-comparison-slider": "^3.0.4"
}
},
"@mdx-js/mdx": {
"version": "1.6.22",
"resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-1.6.22.tgz",
@ -5654,6 +5662,11 @@
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz",
"integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw=="
},
"img-comparison-slider": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/img-comparison-slider/-/img-comparison-slider-3.0.4.tgz",
"integrity": "sha512-N5ApBNNNH8s1YoYdKCxGKgKxG2Fj6GjFMKWs3lEWF5UFBiqPpDwyf1Tna4uLJDMy2lpihCdbdTRFFww31i312w=="
},
"immer": {
"version": "8.0.1",
"resolved": "https://registry.npmjs.org/immer/-/immer-8.0.1.tgz",

View File

@ -16,6 +16,7 @@
"@docusaurus/core": "2.0.0-alpha.75",
"@docusaurus/preset-classic": "2.0.0-alpha.75",
"@icons-pack/react-simple-icons": "^4.2.0",
"@img-comparison-slider/react": "^3.0.4",
"@mdx-js/react": "^1.6.21",
"@svgr/webpack": "^5.5.0",
"clsx": "^1.1.1",

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 899 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 941 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 931 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 636 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 489 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 444 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 688 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 660 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

View File

@ -0,0 +1,46 @@
<svg id="livetype" xmlns="http://www.w3.org/2000/svg" width="119.66407" height="40" viewBox="0 0 119.66407 40">
<title>Download_on_the_App_Store_Badge_US-UK_RGB_blk_4SVG_092917</title>
<g>
<g>
<g>
<path d="M110.13477,0H9.53468c-.3667,0-.729,0-1.09473.002-.30615.002-.60986.00781-.91895.0127A13.21476,13.21476,0,0,0,5.5171.19141a6.66509,6.66509,0,0,0-1.90088.627A6.43779,6.43779,0,0,0,1.99757,1.99707,6.25844,6.25844,0,0,0,.81935,3.61816a6.60119,6.60119,0,0,0-.625,1.90332,12.993,12.993,0,0,0-.1792,2.002C.00587,7.83008.00489,8.1377,0,8.44434V31.5586c.00489.3105.00587.6113.01515.9219a12.99232,12.99232,0,0,0,.1792,2.0019,6.58756,6.58756,0,0,0,.625,1.9043A6.20778,6.20778,0,0,0,1.99757,38.001a6.27445,6.27445,0,0,0,1.61865,1.1787,6.70082,6.70082,0,0,0,1.90088.6308,13.45514,13.45514,0,0,0,2.0039.1768c.30909.0068.6128.0107.91895.0107C8.80567,40,9.168,40,9.53468,40H110.13477c.3594,0,.7246,0,1.084-.002.3047,0,.6172-.0039.9219-.0107a13.279,13.279,0,0,0,2-.1768,6.80432,6.80432,0,0,0,1.9082-.6308,6.27742,6.27742,0,0,0,1.6172-1.1787,6.39482,6.39482,0,0,0,1.1816-1.6143,6.60413,6.60413,0,0,0,.6191-1.9043,13.50643,13.50643,0,0,0,.1856-2.0019c.0039-.3106.0039-.6114.0039-.9219.0078-.3633.0078-.7246.0078-1.0938V9.53613c0-.36621,0-.72949-.0078-1.09179,0-.30664,0-.61426-.0039-.9209a13.5071,13.5071,0,0,0-.1856-2.002,6.6177,6.6177,0,0,0-.6191-1.90332,6.46619,6.46619,0,0,0-2.7988-2.7998,6.76754,6.76754,0,0,0-1.9082-.627,13.04394,13.04394,0,0,0-2-.17676c-.3047-.00488-.6172-.01074-.9219-.01269-.3594-.002-.7246-.002-1.084-.002Z" style="fill: #a6a6a6"/>
<path d="M8.44483,39.125c-.30468,0-.602-.0039-.90429-.0107a12.68714,12.68714,0,0,1-1.86914-.1631,5.88381,5.88381,0,0,1-1.65674-.5479,5.40573,5.40573,0,0,1-1.397-1.0166,5.32082,5.32082,0,0,1-1.02051-1.3965,5.72186,5.72186,0,0,1-.543-1.6572,12.41351,12.41351,0,0,1-.1665-1.875c-.00634-.2109-.01464-.9131-.01464-.9131V8.44434S.88185,7.75293.8877,7.5498a12.37039,12.37039,0,0,1,.16553-1.87207,5.7555,5.7555,0,0,1,.54346-1.6621A5.37349,5.37349,0,0,1,2.61183,2.61768,5.56543,5.56543,0,0,1,4.01417,1.59521a5.82309,5.82309,0,0,1,1.65332-.54394A12.58589,12.58589,0,0,1,7.543.88721L8.44532.875H111.21387l.9131.0127a12.38493,12.38493,0,0,1,1.8584.16259,5.93833,5.93833,0,0,1,1.6709.54785,5.59374,5.59374,0,0,1,2.415,2.41993,5.76267,5.76267,0,0,1,.5352,1.64892,12.995,12.995,0,0,1,.1738,1.88721c.0029.2832.0029.5874.0029.89014.0079.375.0079.73193.0079,1.09179V30.4648c0,.3633,0,.7178-.0079,1.0752,0,.3252,0,.6231-.0039.9297a12.73126,12.73126,0,0,1-.1709,1.8535,5.739,5.739,0,0,1-.54,1.67,5.48029,5.48029,0,0,1-1.0156,1.3857,5.4129,5.4129,0,0,1-1.3994,1.0225,5.86168,5.86168,0,0,1-1.668.5498,12.54218,12.54218,0,0,1-1.8692.1631c-.2929.0068-.5996.0107-.8974.0107l-1.084.002Z"/>
</g>
<g id="_Group_" data-name="&lt;Group&gt;">
<g id="_Group_2" data-name="&lt;Group&gt;">
<g id="_Group_3" data-name="&lt;Group&gt;">
<path id="_Path_" data-name="&lt;Path&gt;" d="M24.76888,20.30068a4.94881,4.94881,0,0,1,2.35656-4.15206,5.06566,5.06566,0,0,0-3.99116-2.15768c-1.67924-.17626-3.30719,1.00483-4.1629,1.00483-.87227,0-2.18977-.98733-3.6085-.95814a5.31529,5.31529,0,0,0-4.47292,2.72787c-1.934,3.34842-.49141,8.26947,1.3612,10.97608.9269,1.32535,2.01018,2.8058,3.42763,2.7533,1.38706-.05753,1.9051-.88448,3.5794-.88448,1.65876,0,2.14479.88448,3.591.8511,1.48838-.02416,2.42613-1.33124,3.32051-2.66914a10.962,10.962,0,0,0,1.51842-3.09251A4.78205,4.78205,0,0,1,24.76888,20.30068Z" style="fill: #fff"/>
<path id="_Path_2" data-name="&lt;Path&gt;" d="M22.03725,12.21089a4.87248,4.87248,0,0,0,1.11452-3.49062,4.95746,4.95746,0,0,0-3.20758,1.65961,4.63634,4.63634,0,0,0-1.14371,3.36139A4.09905,4.09905,0,0,0,22.03725,12.21089Z" style="fill: #fff"/>
</g>
</g>
<g>
<path d="M42.30227,27.13965h-4.7334l-1.13672,3.35645H34.42727l4.4834-12.418h2.083l4.4834,12.418H43.438ZM38.0591,25.59082h3.752l-1.84961-5.44727h-.05176Z" style="fill: #fff"/>
<path d="M55.15969,25.96973c0,2.81348-1.50586,4.62109-3.77832,4.62109a3.0693,3.0693,0,0,1-2.84863-1.584h-.043v4.48438h-1.8584V21.44238H48.4302v1.50586h.03418a3.21162,3.21162,0,0,1,2.88281-1.60059C53.645,21.34766,55.15969,23.16406,55.15969,25.96973Zm-1.91016,0c0-1.833-.94727-3.03809-2.39258-3.03809-1.41992,0-2.375,1.23047-2.375,3.03809,0,1.82422.95508,3.0459,2.375,3.0459C52.30227,29.01563,53.24953,27.81934,53.24953,25.96973Z" style="fill: #fff"/>
<path d="M65.12453,25.96973c0,2.81348-1.50586,4.62109-3.77832,4.62109a3.0693,3.0693,0,0,1-2.84863-1.584h-.043v4.48438h-1.8584V21.44238H58.395v1.50586h.03418A3.21162,3.21162,0,0,1,61.312,21.34766C63.60988,21.34766,65.12453,23.16406,65.12453,25.96973Zm-1.91016,0c0-1.833-.94727-3.03809-2.39258-3.03809-1.41992,0-2.375,1.23047-2.375,3.03809,0,1.82422.95508,3.0459,2.375,3.0459C62.26711,29.01563,63.21438,27.81934,63.21438,25.96973Z" style="fill: #fff"/>
<path d="M71.71047,27.03613c.1377,1.23145,1.334,2.04,2.96875,2.04,1.56641,0,2.69336-.80859,2.69336-1.91895,0-.96387-.67969-1.541-2.28906-1.93652l-1.60937-.3877c-2.28027-.55078-3.33887-1.61719-3.33887-3.34766,0-2.14258,1.86719-3.61426,4.51855-3.61426,2.624,0,4.42285,1.47168,4.4834,3.61426h-1.876c-.1123-1.23926-1.13672-1.9873-2.63379-1.9873s-2.52148.75684-2.52148,1.8584c0,.87793.6543,1.39453,2.25488,1.79l1.36816.33594c2.54785.60254,3.60645,1.626,3.60645,3.44238,0,2.32324-1.85059,3.77832-4.79395,3.77832-2.75391,0-4.61328-1.4209-4.7334-3.667Z" style="fill: #fff"/>
<path d="M83.34621,19.2998v2.14258h1.72168v1.47168H83.34621v4.99121c0,.77539.34473,1.13672,1.10156,1.13672a5.80752,5.80752,0,0,0,.61133-.043v1.46289a5.10351,5.10351,0,0,1-1.03223.08594c-1.833,0-2.54785-.68848-2.54785-2.44434V22.91406H80.16262V21.44238H81.479V19.2998Z" style="fill: #fff"/>
<path d="M86.065,25.96973c0-2.84863,1.67773-4.63867,4.29395-4.63867,2.625,0,4.29492,1.79,4.29492,4.63867,0,2.85645-1.66113,4.63867-4.29492,4.63867C87.72609,30.6084,86.065,28.82617,86.065,25.96973Zm6.69531,0c0-1.9541-.89551-3.10742-2.40137-3.10742s-2.40039,1.16211-2.40039,3.10742c0,1.96191.89453,3.10645,2.40039,3.10645S92.76027,27.93164,92.76027,25.96973Z" style="fill: #fff"/>
<path d="M96.18606,21.44238h1.77246v1.541h.043a2.1594,2.1594,0,0,1,2.17773-1.63574,2.86616,2.86616,0,0,1,.63672.06934v1.73828a2.59794,2.59794,0,0,0-.835-.1123,1.87264,1.87264,0,0,0-1.93652,2.083v5.37012h-1.8584Z" style="fill: #fff"/>
<path d="M109.3843,27.83691c-.25,1.64355-1.85059,2.77148-3.89844,2.77148-2.63379,0-4.26855-1.76465-4.26855-4.5957,0-2.83984,1.64355-4.68164,4.19043-4.68164,2.50488,0,4.08008,1.7207,4.08008,4.46582v.63672h-6.39453v.1123a2.358,2.358,0,0,0,2.43555,2.56445,2.04834,2.04834,0,0,0,2.09082-1.27344Zm-6.28223-2.70215h4.52637a2.1773,2.1773,0,0,0-2.2207-2.29785A2.292,2.292,0,0,0,103.10207,25.13477Z" style="fill: #fff"/>
</g>
</g>
</g>
<g id="_Group_4" data-name="&lt;Group&gt;">
<g>
<path d="M37.82619,8.731a2.63964,2.63964,0,0,1,2.80762,2.96484c0,1.90625-1.03027,3.002-2.80762,3.002H35.67092V8.731Zm-1.22852,5.123h1.125a1.87588,1.87588,0,0,0,1.96777-2.146,1.881,1.881,0,0,0-1.96777-2.13379h-1.125Z" style="fill: #fff"/>
<path d="M41.68068,12.44434a2.13323,2.13323,0,1,1,4.24707,0,2.13358,2.13358,0,1,1-4.24707,0Zm3.333,0c0-.97607-.43848-1.54687-1.208-1.54687-.77246,0-1.207.5708-1.207,1.54688,0,.98389.43457,1.55029,1.207,1.55029C44.57522,13.99463,45.01369,13.42432,45.01369,12.44434Z" style="fill: #fff"/>
<path d="M51.57326,14.69775h-.92187l-.93066-3.31641h-.07031l-.92676,3.31641h-.91309l-1.24121-4.50293h.90137l.80664,3.436h.06641l.92578-3.436h.85254l.92578,3.436h.07031l.80273-3.436h.88867Z" style="fill: #fff"/>
<path d="M53.85354,10.19482H54.709v.71533h.06641a1.348,1.348,0,0,1,1.34375-.80225,1.46456,1.46456,0,0,1,1.55859,1.6748v2.915h-.88867V12.00586c0-.72363-.31445-1.0835-.97168-1.0835a1.03294,1.03294,0,0,0-1.0752,1.14111v2.63428h-.88867Z" style="fill: #fff"/>
<path d="M59.09377,8.437h.88867v6.26074h-.88867Z" style="fill: #fff"/>
<path d="M61.21779,12.44434a2.13346,2.13346,0,1,1,4.24756,0,2.1338,2.1338,0,1,1-4.24756,0Zm3.333,0c0-.97607-.43848-1.54687-1.208-1.54687-.77246,0-1.207.5708-1.207,1.54688,0,.98389.43457,1.55029,1.207,1.55029C64.11232,13.99463,64.5508,13.42432,64.5508,12.44434Z" style="fill: #fff"/>
<path d="M66.4009,13.42432c0-.81055.60352-1.27783,1.6748-1.34424l1.21973-.07031v-.38867c0-.47559-.31445-.74414-.92187-.74414-.49609,0-.83984.18213-.93848.50049h-.86035c.09082-.77344.81836-1.26953,1.83984-1.26953,1.12891,0,1.76563.562,1.76563,1.51318v3.07666h-.85547v-.63281h-.07031a1.515,1.515,0,0,1-1.35254.707A1.36026,1.36026,0,0,1,66.4009,13.42432Zm2.89453-.38477v-.37646l-1.09961.07031c-.62012.0415-.90137.25244-.90137.64941,0,.40527.35156.64111.835.64111A1.0615,1.0615,0,0,0,69.29543,13.03955Z" style="fill: #fff"/>
<path d="M71.34816,12.44434c0-1.42285.73145-2.32422,1.86914-2.32422a1.484,1.484,0,0,1,1.38086.79h.06641V8.437h.88867v6.26074h-.85156v-.71143h-.07031a1.56284,1.56284,0,0,1-1.41406.78564C72.0718,14.772,71.34816,13.87061,71.34816,12.44434Zm.918,0c0,.95508.4502,1.52979,1.20313,1.52979.749,0,1.21191-.583,1.21191-1.52588,0-.93848-.46777-1.52979-1.21191-1.52979C72.72121,10.91846,72.26613,11.49707,72.26613,12.44434Z" style="fill: #fff"/>
<path d="M79.23,12.44434a2.13323,2.13323,0,1,1,4.24707,0,2.13358,2.13358,0,1,1-4.24707,0Zm3.333,0c0-.97607-.43848-1.54687-1.208-1.54687-.77246,0-1.207.5708-1.207,1.54688,0,.98389.43457,1.55029,1.207,1.55029C82.12453,13.99463,82.563,13.42432,82.563,12.44434Z" style="fill: #fff"/>
<path d="M84.66945,10.19482h.85547v.71533h.06641a1.348,1.348,0,0,1,1.34375-.80225,1.46456,1.46456,0,0,1,1.55859,1.6748v2.915H87.605V12.00586c0-.72363-.31445-1.0835-.97168-1.0835a1.03294,1.03294,0,0,0-1.0752,1.14111v2.63428h-.88867Z" style="fill: #fff"/>
<path d="M93.51516,9.07373v1.1416h.97559v.74854h-.97559V13.2793c0,.47168.19434.67822.63672.67822a2.96657,2.96657,0,0,0,.33887-.02051v.74023a2.9155,2.9155,0,0,1-.4834.04541c-.98828,0-1.38184-.34766-1.38184-1.21582v-2.543h-.71484v-.74854h.71484V9.07373Z" style="fill: #fff"/>
<path d="M95.70461,8.437h.88086v2.48145h.07031a1.3856,1.3856,0,0,1,1.373-.80664,1.48339,1.48339,0,0,1,1.55078,1.67871v2.90723H98.69v-2.688c0-.71924-.335-1.0835-.96289-1.0835a1.05194,1.05194,0,0,0-1.13379,1.1416v2.62988h-.88867Z" style="fill: #fff"/>
<path d="M104.76125,13.48193a1.828,1.828,0,0,1-1.95117,1.30273A2.04531,2.04531,0,0,1,100.73,12.46045a2.07685,2.07685,0,0,1,2.07617-2.35254c1.25293,0,2.00879.856,2.00879,2.27V12.688h-3.17969v.0498a1.1902,1.1902,0,0,0,1.19922,1.29,1.07934,1.07934,0,0,0,1.07129-.5459Zm-3.126-1.45117h2.27441a1.08647,1.08647,0,0,0-1.1084-1.1665A1.15162,1.15162,0,0,0,101.63527,12.03076Z" style="fill: #fff"/>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

View File

@ -0,0 +1,82 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 18.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 864 312" enable-background="new 0 0 864 312" xml:space="preserve">
<g id="Layer_2">
<rect x="2.3" y="2.3" width="859.5" height="307.5"/>
<path fill="#D2D2D2" d="M4.5,4.5h855v303H4.5V4.5z M0,312h864V0H0V312z"/>
<g>
<defs>
<rect id="SVGID_1_" y="0" width="864" height="312"/>
</defs>
<clipPath id="SVGID_2_">
<use xlink:href="#SVGID_1_" overflow="visible"/>
</clipPath>
</g>
</g>
<g id="Layer_1">
<rect x="70.5" y="68.6" fill="#F25022" width="83.8" height="83.8"/>
<rect x="163" y="68.6" fill="#7FBA00" width="83.8" height="83.8"/>
<rect x="70.5" y="161" fill="#00A4EF" width="83.8" height="83.8"/>
<rect x="163" y="161" fill="#FFB900" width="83.8" height="83.8"/>
<path fill="#FFFFFF" d="M408.3,163c0-2.5,0.9-4.5,2.7-6.2c1.8-1.7,3.9-2.5,6.4-2.5c2.6,0,4.8,0.9,6.5,2.6c1.7,1.7,2.6,3.8,2.6,6.1
c0,2.4-0.9,4.5-2.7,6.1c-1.8,1.7-3.9,2.5-6.5,2.5c-2.6,0-4.7-0.8-6.5-2.5C409.2,167.4,408.3,165.4,408.3,163 M424.8,244.8h-14.9
v-63.5h14.9V244.8z"/>
<path fill="#FFFFFF" d="M470.2,233.9c2.2,0,4.7-0.5,7.4-1.5c2.7-1,5.1-2.4,7.4-4.1v13.9c-2.4,1.4-5.1,2.4-8.1,3.1
c-3,0.7-6.4,1.1-10,1.1c-9.3,0-16.9-3-22.8-8.9c-5.9-5.9-8.8-13.5-8.8-22.6c0-10.2,3-18.6,9-25.2c6-6.6,14.4-9.9,25.4-9.9
c2.8,0,5.6,0.4,8.5,1.1c2.9,0.7,5.1,1.6,6.8,2.5v14.3c-2.3-1.7-4.7-3-7.1-3.9c-2.4-0.9-4.9-1.4-7.4-1.4c-5.9,0-10.6,1.9-14.3,5.7
c-3.6,3.8-5.4,9-5.4,15.5c0,6.4,1.7,11.4,5.2,15C459.5,232.2,464.2,233.9,470.2,233.9"/>
<path fill="#FFFFFF" d="M527.5,180.3c1.2,0,2.3,0.1,3.2,0.2c0.9,0.2,1.8,0.4,2.4,0.6v15.1c-0.8-0.6-1.9-1.1-3.4-1.6
c-1.5-0.5-3.3-0.8-5.5-0.8c-3.7,0-6.8,1.5-9.3,4.6c-2.5,3.1-3.8,7.8-3.8,14.3v32.1h-14.9v-63.5h14.9v10h0.2
c1.4-3.5,3.4-6.2,6.2-8.1C520.3,181.3,523.6,180.3,527.5,180.3"/>
<path fill="#FFFFFF" d="M533.9,214c0-10.5,3-18.8,8.9-25c5.9-6.1,14.2-9.2,24.7-9.2c9.9,0,17.7,3,23.3,8.9
c5.6,5.9,8.4,13.9,8.4,23.9c0,10.3-3,18.5-8.9,24.6c-5.9,6.1-14,9.1-24.2,9.1c-9.8,0-17.7-2.9-23.4-8.7
C536.8,231.9,533.9,224,533.9,214 M549.5,213.5c0,6.6,1.5,11.7,4.5,15.2c3,3.5,7.3,5.2,12.9,5.2c5.4,0,9.6-1.7,12.4-5.2
s4.3-8.7,4.3-15.6c0-6.8-1.5-12-4.4-15.5c-2.9-3.5-7.1-5.2-12.4-5.2c-5.5,0-9.7,1.8-12.8,5.5C551,201.6,549.5,206.7,549.5,213.5"/>
<path fill="#FFFFFF" d="M621.4,198c0,2.1,0.7,3.8,2,5c1.4,1.2,4.4,2.7,9,4.6c6,2.4,10.2,5.1,12.6,8.1c2.4,3,3.6,6.6,3.6,10.8
c0,6-2.3,10.8-6.9,14.4c-4.6,3.6-10.8,5.4-18.6,5.4c-2.6,0-5.5-0.3-8.7-1c-3.2-0.6-5.9-1.5-8.1-2.4v-14.7c2.7,1.9,5.6,3.4,8.8,4.5
c3.1,1.1,6,1.7,8.5,1.7c3.4,0,5.9-0.5,7.5-1.4c1.6-0.9,2.4-2.5,2.4-4.8c0-2.1-0.8-3.8-2.5-5.2c-1.7-1.4-4.8-3.1-9.5-4.9
c-5.5-2.3-9.4-4.9-11.7-7.8c-2.3-2.9-3.5-6.6-3.5-11c0-5.7,2.3-10.4,6.8-14.1c4.5-3.7,10.4-5.5,17.7-5.5c2.2,0,4.7,0.2,7.5,0.7
c2.8,0.5,5.1,1.1,6.9,1.9v14.2c-2-1.3-4.3-2.4-6.9-3.4c-2.6-0.9-5.3-1.4-7.8-1.4c-2.8,0-5.1,0.6-6.6,1.7
C622.2,194.5,621.4,196.1,621.4,198"/>
<path fill="#FFFFFF" d="M655.2,214c0-10.5,3-18.8,8.9-25c5.9-6.1,14.2-9.2,24.7-9.2c9.9,0,17.7,3,23.3,8.9
c5.6,5.9,8.4,13.9,8.4,23.9c0,10.3-3,18.5-8.9,24.6c-5.9,6.1-14,9.1-24.2,9.1c-9.8,0-17.7-2.9-23.4-8.7
C658.1,231.9,655.2,224,655.2,214 M670.7,213.5c0,6.6,1.5,11.7,4.5,15.2c3,3.5,7.3,5.2,12.9,5.2c5.4,0,9.6-1.7,12.4-5.2
s4.3-8.7,4.3-15.6c0-6.8-1.5-12-4.4-15.5s-7.1-5.2-12.4-5.2c-5.5,0-9.7,1.8-12.8,5.5C672.2,201.6,670.7,206.7,670.7,213.5"/>
<path fill="#FFFFFF" d="M769.8,193.6v32.6c0,6.8,1.6,11.8,4.7,15.2c3.1,3.4,7.9,5,14.2,5c2.1,0,4.3-0.2,6.5-0.7
c2.2-0.5,3.8-0.9,4.7-1.5v-12.4c-0.9,0.6-2,1.1-3.2,1.5c-1.2,0.4-2.3,0.6-3.1,0.6c-3,0-5.3-0.8-6.7-2.4c-1.4-1.6-2.1-4.4-2.1-8.3
v-29.7H800v-12.2h-15.1v-18.8l-15,4.6v14.3h-22.3v-7.7c0-3.8,0.8-6.7,2.5-8.7c1.7-2,4.1-2.9,7.2-2.9c1.6,0,3,0.2,4.3,0.6
c1.2,0.4,2.1,0.8,2.6,1.1v-12.9c-1.1-0.4-2.3-0.6-3.7-0.8c-1.4-0.2-3-0.3-4.8-0.3c-6.8,0-12.4,2.1-16.7,6.4
c-4.3,4.3-6.5,9.7-6.5,16.4v8.8h-10.6v12.2h10.6v51.3h15.1v-51.3H769.8z"/>
<polygon fill="#FFFFFF" points="395.5,156.2 395.5,244.8 380.1,244.8 380.1,175.4 379.9,175.4 352.4,244.8 342.2,244.8 314,175.4
313.8,175.4 313.8,244.8 299.6,244.8 299.6,156.2 321.6,156.2 347.1,221.9 347.5,221.9 374.4,156.2 "/>
<path fill="#FFFFFF" d="M340,117.9c-5.3,3-11.3,4.5-18,4.5c-5.1,0-9.6-1.1-13.6-3.4c-3.9-2.2-7-5.4-9.1-9.5
c-2.1-4.1-3.2-8.7-3.2-13.8c0-5.4,1.2-10.3,3.5-14.5s5.6-7.6,9.9-10c4.3-2.4,9.1-3.6,14.5-3.6c2.7,0,5.4,0.3,8.1,0.8
c2.7,0.5,4.9,1.2,6.6,2v8c-4-2.7-9.1-4-15.3-4c-3.7,0-7,0.9-10,2.7c-3,1.8-5.3,4.3-6.9,7.4c-1.6,3.2-2.4,6.8-2.4,10.8
c0,6.3,1.7,11.3,5,15c3.3,3.7,7.9,5.5,13.7,5.5c3.7,0,7-0.7,9.8-2.2V99.9h-11.3v-6.6H340V117.9z"/>
<path fill="#FFFFFF" d="M383.1,104.6h-26.2c0.1,3.8,1.3,6.7,3.3,8.8c2.1,2,4.8,3.1,8.2,3.1c4.5,0,8.4-1.3,11.8-3.9v6.4
c-1.5,1-3.4,1.9-5.7,2.5c-2.3,0.6-4.7,0.9-7.1,0.9c-5.7,0-10.2-1.7-13.3-5.1c-3.1-3.4-4.7-8.2-4.7-14.4c0-3.8,0.8-7.3,2.3-10.3
c1.5-3.1,3.7-5.5,6.4-7.2c2.7-1.7,5.8-2.6,9.1-2.6c4.9,0,8.8,1.6,11.6,4.8c2.8,3.2,4.2,7.6,4.2,13.3V104.6z M375.8,98.9
c0-3.3-0.8-5.8-2.3-7.5c-1.5-1.7-3.6-2.6-6.4-2.6c-2.5,0-4.7,0.9-6.6,2.7s-3,4.3-3.6,7.4H375.8z"/>
<path fill="#FFFFFF" d="M411.5,121.1c-0.7,0.4-1.6,0.7-2.9,0.9c-1.2,0.2-2.3,0.3-3.3,0.3c-7,0-10.5-3.9-10.5-11.6V89.7h-6.4v-6h6.4
v-9l7.3-2.3v11.2h9.3v6h-9.3v19.8c0,2.5,0.4,4.3,1.2,5.3c0.8,1,2.2,1.5,4.3,1.5c1.4,0,2.7-0.4,3.8-1.2V121.1z"/>
<path fill="#FFFFFF" d="M447.7,70.3c0,1.2-0.4,2.2-1.3,3.1c-0.9,0.9-2,1.3-3.3,1.3c-1.3,0-2.4-0.4-3.3-1.3
c-0.9-0.8-1.3-1.9-1.3-3.2c0-1.3,0.5-2.4,1.4-3.2c0.9-0.8,2-1.3,3.2-1.3c1.2,0,2.3,0.4,3.2,1.3C447.3,68,447.7,69,447.7,70.3
M446.7,121.5h-7.3V83.7h7.3V121.5z"/>
<path fill="#FFFFFF" d="M478.4,121.1c-0.7,0.4-1.6,0.7-2.9,0.9c-1.2,0.2-2.3,0.3-3.3,0.3c-7,0-10.5-3.9-10.5-11.6V89.7h-6.4v-6h6.4
v-9l7.3-2.3v11.2h9.3v6h-9.3v19.8c0,2.5,0.4,4.3,1.2,5.3c0.8,1,2.2,1.5,4.3,1.5c1.4,0,2.7-0.4,3.8-1.2V121.1z"/>
<path fill="#FFFFFF" d="M526.2,71.7c-1.2-0.6-2.5-1-4-1c-4.1,0-6.1,2.5-6.1,7.5v5.4h8.6v6h-8.6v31.8h-7.3V89.7h-6.4v-6h6.4v-5.8
c0-4,1.1-7.2,3.4-9.6c2.3-2.4,5.4-3.6,9.4-3.6c2,0,3.5,0.2,4.7,0.7V71.7z"/>
<path fill="#FFFFFF" d="M553.1,91c-0.4-0.3-1.2-0.6-2.2-0.9c-1-0.2-1.9-0.4-2.6-0.4c-2.6,0-4.7,1.2-6.3,3.5c-1.6,2.3-2.4,5.3-2.4,9
v19.3h-7.3V83.7h7.3v7.6h0.2c0.8-2.6,2.1-4.6,3.8-6.1c1.7-1.5,3.7-2.2,5.9-2.2c1.5,0,2.7,0.2,3.5,0.5V91z"/>
<path fill="#FFFFFF" d="M594.8,102.4c0,6.1-1.8,11-5.3,14.6c-3.5,3.6-8.2,5.4-14,5.4c-5.7,0-10.3-1.8-13.7-5.3
c-3.4-3.5-5.1-8.2-5.1-14.1c0-6.3,1.8-11.2,5.3-14.8c3.5-3.6,8.3-5.4,14.4-5.4c5.7,0,10.2,1.7,13.4,5.2
C593.2,91.5,594.8,96.3,594.8,102.4 M587.3,102.6c0-4.5-1-7.9-2.9-10.2c-2-2.3-4.7-3.5-8.3-3.5c-3.6,0-6.5,1.2-8.6,3.7
c-2.1,2.4-3.1,5.9-3.1,10.3c0,4.3,1,7.6,3.1,10c2.1,2.4,4.9,3.6,8.6,3.6c3.7,0,6.5-1.2,8.4-3.5
C586.3,110.5,587.3,107.1,587.3,102.6"/>
<path fill="#FFFFFF" d="M660.1,121.5h-7.3V100c0-3.9-0.6-6.7-1.8-8.5c-1.2-1.8-3.3-2.6-6.2-2.6c-2.4,0-4.5,1.1-6.1,3.3
c-1.7,2.2-2.5,4.9-2.5,7.9v21.4h-7.3V99.3c0-6.9-2.7-10.4-8-10.4c-2.5,0-4.6,1.1-6.2,3.2s-2.4,4.8-2.4,8.1v21.4h-7.3V83.7h7.3v5.9
h0.1c2.7-4.6,6.7-6.8,11.8-6.8c2.4,0,4.6,0.7,6.6,2c1.9,1.3,3.3,3.2,4.2,5.6c1.5-2.6,3.2-4.5,5.3-5.8c2.1-1.2,4.5-1.9,7.3-1.9
c8.3,0,12.4,5.1,12.4,15.4V121.5z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 7.1 KiB