Install multimedia codecs

Install the `gstreamer1-plugins-good`, `gstreamer1-plugins-bad`, and `gstreamer1-plugins-ugly` packages from the RPM Fusion repository, as Fedora does not include proprietary multimedia codecs in its official repositories due to licensing restrictions.

The black screen after a fresh install

You just finished a clean install of Fedora Workstation. The desktop looks crisp. The terminal responds instantly. You open Firefox and navigate to a video site. The video area stays black. A small icon appears with the text "Missing codec." Or you open VLC and the audio stutters while the video freezes. The system works, but the media does not.

This is the first wall every Fedora user hits. The operating system is functional, but it cannot play the formats the internet uses every day. The fix requires enabling an external repository and installing the GStreamer plugin stack. The process takes less than a minute, but understanding the repository structure prevents dependency conflicts later.

Why Fedora excludes codecs

Fedora does not include proprietary multimedia codecs in its official repositories. This is a legal decision, not a technical limitation. Formats like H.264, AAC, and MP3 involve patent pools and licensing fees. Fedora cannot distribute software that requires the user to accept a proprietary license or pay royalties. The result is a clean, legally safe base system.

RPM Fusion fills this gap. It is a community-maintained repository that packages these codecs and makes them available via dnf. RPM Fusion splits its content into two repositories. The free repository contains open-source additions that Fedora excludes for policy reasons. The non-free repository contains proprietary codecs and drivers. You need both to get full multimedia support.

How GStreamer handles media

Fedora uses GStreamer as the core multimedia framework. GStreamer operates on a pipeline architecture. Applications like Firefox, VLC, and GNOME Videos do not decode video themselves. They request elements from GStreamer to build a pipeline. A plugin provides the element. The element handles the decoding.

The package names reflect the quality and licensing of the plugins. The good plugins are standard, well-tested, and open-source. The bad plugins work but require more testing or have incomplete features. The ugly plugins have licensing restrictions that prevent distribution in some regions. Fedora classifies these packages carefully. Installing the full stack ensures every application can find the element it needs.

Enable RPM Fusion

You must enable the RPM Fusion repositories before you can install the codecs. The installation command downloads a release package. The package installs .repo files in /etc/yum.repos.d/. It configures dnf to trust the repository and set the correct priorities.

Run the following command to enable both the free and non-free repositories. The command uses rpm -E %fedora to detect your release number automatically. This ensures the URL matches your system, whether you are on Fedora 40, 41, or a future release.

sudo dnf install https://download1.rpmfusion.org/free/fedora/rpmfusion-free-release-$(rpm -E %fedora).noarch.rpm https://download1.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-$(rpm -E %fedora).noarch.rpm
# WHY: rpm -E %fedora expands to the current release number, e.g., 40.
# WHY: The free repo contains open-source additions excluded by Fedora policy.
# WHY: The non-free repo contains proprietary codecs like H.264 and AAC.
# WHY: dnf resolves dependencies and installs the repo configuration files.

The command outputs a transaction summary. Review the packages. The release package installs a small set of configuration files. It does not install codecs yet. Press y to proceed.

Install the multimedia stack

Once the repositories are active, install the codecs. The recommended approach is to install the Multimedia group. The group is a meta-package. It pulls in the core GStreamer plugins, ffmpeg, and related tools in one transaction. Using the group ensures you get updates for all components when you run dnf upgrade --refresh.

Run the group install command to add the full stack.

sudo dnf groupinstall "Multimedia"
# WHY: The Multimedia group is a meta-package that aggregates all required codecs.
# WHY: Group installs ensure consistency. You get updates for all plugins together.
# WHY: This command installs gstreamer1-plugins-good, bad, and ugly in one step.

If you are building a minimal server and only need specific decoding capabilities, install the individual packages. This approach gives you control over the package set. It also reduces the attack surface by excluding unused plugins.

sudo dnf install gstreamer1-plugins-good gstreamer1-plugins-bad-free gstreamer1-plugins-bad-free-extras gstreamer1-plugins-ugly-free
# WHY: 'good' plugins are standard and open-source.
# WHY: 'bad' plugins work but may need testing. 'bad-free-extras' adds extra formats.
# WHY: 'ugly' plugins have licensing restrictions but provide essential codecs.
# WHY: Manual installs require you to track updates for each package individually.

Firefox and hardware acceleration

Firefox uses ffmpeg for hardware-accelerated decoding. The browser links against the shared libraries provided by the ffmpeg package. If Firefox still shows a black screen after installing the GStreamer plugins, the ffmpeg package might be missing.

Install ffmpeg to provide the underlying decoding libraries.

sudo dnf install ffmpeg
# WHY: Firefox uses ffmpeg for hardware-accelerated video decoding.
# WHY: The package provides shared libraries the browser links against at runtime.
# WHY: Reinstalling ffmpeg ensures the libraries match the current kernel headers.

Reboot the browser after installing ffmpeg. The process caches libraries on startup. A restart forces Firefox to reload the new libraries.

Verify the installation

Confirm that GStreamer recognizes the new codecs. The gst-inspect-1.0 command queries the GStreamer registry. It lists all available elements. Pipe the output to grep to filter for specific formats.

Run the inspection command to check for H.264 support.

gst-inspect-1.0 | grep -i h264
# WHY: gst-inspect-1.0 queries the GStreamer registry for available elements.
# WHY: grep filters the output to show only H.264 related elements.
# WHY: The output should list avdec_h264 and avenc_h264 from the ffmpeg plugin.

The output should show avdec_h264 and avenc_h264. These elements come from the gstreamer1-plugins-bad-free-extras package. If the list is empty, the plugins did not install correctly. Check the dnf transaction log for errors.

Common pitfalls

SELinux denials

If you are using SELinux in enforcing mode, you might see permission errors during playback. SELinux protects the system by restricting access to resources. A denial usually means a process tried to access a file or socket without the correct context.

Check the audit log for GStreamer denials. Use ausearch to read the log. The -m avc flag filters for Access Vector Cache denials. The -ts recent flag shows only recent events.

sudo ausearch -m avc -ts recent | grep -i gstreamer
# WHY: ausearch reads the audit log.
# WHY: -m avc filters for Access Vector Cache denials.
# WHY: -ts recent shows only events from the last few minutes.
# WHY: grep isolates gstreamer related denials from the full log.

In most cases, the denial points to a missing context on a user file. Run restorecon -Rv /home/$USER to fix the context. Do not disable SELinux. The denial usually resolves after a reboot or a context restore.

Minimal server base packages

If you are using a minimal Fedora Server installation, the base GStreamer package might be missing. The plugins depend on gstreamer1. If the base package is absent, dnf might fail to resolve dependencies.

Install the base package first.

sudo dnf install gstreamer1
# WHY: gstreamer1 provides the core runtime libraries.
# WHY: Plugins depend on the base package. It must be present before installing plugins.
# WHY: Minimal installs exclude multimedia packages to save space.

Repository conflicts

If you see Error: Transaction test error during the install, you might have conflicting packages from a third-party source. Fedora's package manager enforces strict dependency resolution. A package from another repo might provide the same file as RPM Fusion.

Run dnf repoquery --whatprovides <package> to identify the conflict. Remove the conflicting package before retrying. Trust the package manager. Manual file edits drift, snapshots stay.

Decision matrix

Use the Multimedia group when you want a complete set of codecs for desktop playback. Use individual gstreamer packages when you are building a minimal server and only need specific decoding capabilities. Use Flatpak applications when you want the codecs bundled inside the app container without modifying the host system. Use the RPM Fusion non-free repo when you need proprietary drivers for hardware acceleration. Stay on the upstream Workstation defaults if you only deviate from the base system occasionally.

Where to go next