DEV Community

Iñigo Etxaniz
Iñigo Etxaniz

Posted on

Streamlining Home Entertainment: How to Use a Linux Machine for Streaming Content to Smart TVs and More

Introduction

Hey there! Ever thought about turning your old laptop or a Raspberry Pi into a personal streaming powerhouse? You're not alone. Many of us find the idea of ditching the limitations of traditional smart TV platforms (think annoying ads, blocked content, and less-than-stellar USB playback) pretty appealing.

In this guide, I'll walk you through a slightly intricate but rewarding journey to set up your own streaming service. This might be a bit of a lengthy read, but stick with me. By the end, you’ll be able to stream content directly from your laptop to your TV, bypassing those smart TV nuances and enjoying your media just the way you like it.

Let’s dive in and transform the way you experience home entertainment!

Overview of the Setup

We start by adding a new sound interface. This solution eliminates the distraction of audio playing in the speakers of the laptop, channeling all sound directly to OBS for a seamless streaming experience. Then, we install Docker, establishing isolated environments for some of the services of our system. This isolation ensures operational efficiency and prevents interference with other processes on the machine. Next, OBS takes the center stage, adeptly capturing and transmitting both audio and video. It's the key player that brings your content to life, offering user-friendly customization for an optimized streaming setup. Finally, Nginx acts as a versatile powerhouse, adeptly juggling two critical roles. It not only serves as a reverse proxy for OBS, managing the live video streams, but also doubles as a web server. This dual functionality enables Nginx to host the webpage through which your content is accessed, completing the circle of our streaming service. Together, these components interlink and work in harmony, creating a robust and versatile home streaming solution.

In the following sections, we’ll delve deeper into each component, explaining the setup process. Get ready to transform your old laptop or Raspberry Pi into a streaming powerhouse!

Requirements and Preparations

Fine-tuning our setup to match the specific environment of an old laptop, we're demonstrating that high-end hardware isn't a necessity for a functional home streaming service. The chosen machine is a modest Intel i3 with 4GB of RAM, illustrating that even older computers can effectively handle streaming tasks. This setup runs on Ubuntu, a user-friendly operating system that's ideal for such projects. While this guide primarily focuses on Ubuntu, users with different Linux distributions can still follow along, though they might encounter slight variations in the setup process.

Before diving into the streaming setup, updating your Ubuntu system is crucial. Start by opening a terminal; you can usually do this by searching for 'Terminal' in your system's applications menu or by using the shortcut Ctrl + Alt + T. In the terminal, run the following commands to update your system:

sudo apt update
sudo apt upgrade
Enter fullscreen mode Exit fullscreen mode

This process ensures your system is secure and functions smoothly, paving the way for a successful setup. As we proceed, basic command line familiarity will be beneficial, but don't worry—I'll provide all the necessary commands, making it easy to follow along. We'll be configuring an external sound interface to optimize audio output for OBS and installing Docker to run Nginx in a container. This approach keeps our setup clean and modular. Embrace this project with patience and a willingness to learn; it's an exciting journey into the realm of home streaming. With these preparations, we're ready to start building our streaming system, beginning with the new sound interface installation. Let's get started!

Adding a New Sound Interface

Enhancing your streaming setup begins with the addition of a virtual sound interface, a key move for a clean audio experience. This step-by-step guide will help you create a virtual audio streamer on your Linux system, perfect for directing audio to OBS and keeping your laptop's speakers silent.

First, we need to check if PulseAudio, a powerful sound server, is already installed on your machine. Open your terminal and enter:

sudo apt update
sudo apt install pulseaudio
Enter fullscreen mode Exit fullscreen mode

After confirming PulseAudio's installation, the next move is to modify its configuration to add a new virtual sound interface. Using a text editor like Nano, open the PulseAudio configuration file:

sudo nano /etc/pulse/default.pa
Enter fullscreen mode Exit fullscreen mode

Scroll to the end of the file and add the following line:

load-module module-null-sink sink_name=VirtualSink sink_properties=device.description=Virtual_Audio_Streamer
Enter fullscreen mode Exit fullscreen mode

This command instructs PulseAudio to create a new virtual audio output named 'VirtualSink' with the description 'Virtual_Audio_Streamer'. Save the changes and exit the editor. For these changes to take effect, a system restart is necessary.

Once your system is back up, navigate to your sound settings, accessible through the system settings or control panel. In the output section, you will now find 'Virtual_Audio_Streamer' alongside other audio interfaces. Set it as the default output device.

By setting 'Virtual_Audio_Streamer' as the default, the system audio is routed to this virtual sink, meaning you won't hear any sound from your laptop's speakers. Instead, all audio is directed to this virtual interface, ready for OBS to capture.

Installing Docker

Setting up docker on Linux is a straighforward process if you follow the official documentation. If your linux distro is ubuntu you can use the next link Docker's official installation guide ubuntu and if it is debian or raspberry pi 64 bit, you can use the next link Docker's official installation guide ubuntu.

I install following the instructions in Install using the apt repository section. I never had any issues with this method and its quite simple.

I find important to follow post-installation steps just after finishing instalation. This includes adding your user to the Docker group to avoid needing to use sudo for every Docker command. Execute the following commands in your terminal:

sudo groupadd docker
sudo usermod -aG docker $USER
Enter fullscreen mode Exit fullscreen mode

These commands create a new group named 'docker' and add your user to this group. To apply these changes, restart your system. This ensures that your user permissions are updated correctly.

After restarting, you should verify the installation, check if Docker and Docker Compose are correctly installed by running:

docker version
docker compose version
Enter fullscreen mode Exit fullscreen mode

These commands will display the version of Docker and Docker compose installed on your system, confirming that the installation was successful.

By following these steps, you'll have Docker up and running on your system. Docker is an extremely powerful tool for containerization, allowing you to run applications in isolated environments. This will be especially useful for our streaming service setup, where Docker will manage the Nginx server in a container.

Installing OBS Studio on Ubuntu

Installing OBS Studio on your Ubuntu/Debian system is a straightforward process, perfect for beginners, and involves using Ubuntu's or Debian's PPA to ensure easy installation and updates. Type the following command in the terminal to add the OBS Studio PPA:

sudo add-apt-repository ppa:obsproject/obs-studio
Enter fullscreen mode Exit fullscreen mode

This step connects your system to the OBS Studio repository. After adding the PPA, update your system's package list and install OBS studio:

sudo apt update
sudo apt install obs-studio
Enter fullscreen mode Exit fullscreen mode

After installing OBS Studio, hold off on launching it right away. We need to set up Nginx first, as it's a crucial part of our streaming setup. Once Nginx is up and running, we'll circle back to OBS Studio to configure it for streaming. This ensures a smooth integration between your streaming software and the server.

Creating a Web Interface for Streaming

In this part of our setup, we'll create a web interface for the streaming service using Docker and Nginx. This will involve setting up a directory structure and configuring files.

I will not explain how every item works. Docker compose file is quite simple and straightforward, but nginx configuration file was quite tricky as I did not have any previous experience with rtmp and I had to make many different tries till I got a working solution. Web page is also very simple, I did not dedicate much time to this one, I just add a html page with a video player. I did play with other two or three different video players and this one from https://github.com/videojs/video.js, is the one that I liked most and just works fine.

First we need to create a directory for the project. I will use ~/stream-service in my setup:

mkdir ~/stream-service
Enter fullscreen mode Exit fullscreen mode

We will create three directories: ./conf for nginx configuration file, ./hls for the streaming content that will be generated by obs and ./web for hosting index.html file.

cd ~/stream-service
mkdir conf hls web
Enter fullscreen mode Exit fullscreen mode

We will also add in project root folder a docker compose file. This will launch nginx service and redirect container ports to host ports. We will also add a restart: always line so that the service is started automatically when we switch on the laptop. So, create a file called ~/stream-service/docker-compose.yml with the next content:

services:
  nginx:
    image: tiangolo/nginx-rtmp:latest-2023-10-16
    container_name: obs-nginx
    restart: always
    ports:
      - "1935:1935"
      - "80:80"
    volumes:
      - ./conf/obs.conf:/etc/nginx/nginx.conf
      - ./hls:/mnt/hls
      - ./web:/web
Enter fullscreen mode Exit fullscreen mode

Create also the file ~/stream-service/conf/obs.conf file with the next content:

worker_processes auto;
rtmp_auto_push on;
events {}

rtmp {
    server {
        listen 1935;

        application live {
            live on;
            record off;
            hls on;
            hls_path /mnt/hls;
            hls_fragment 3;
            hls_playlist_length 60;
        }
    }
}

http {
    sendfile off;
    tcp_nopush on;
    # aio on;
    directio 512;
    default_type application/octet-stream;

    server {
        listen 80;

        location / {
            # Disable cache
            add_header 'Cache-Control' 'no-cache';

            # CORS setup
            add_header 'Access-Control-Allow-Origin' '*' always;
            add_header 'Access-Control-Expose-Headers' 'Content-Length';

            # allow CORS preflight requests
            if ($request_method = 'OPTIONS') {
                add_header 'Access-Control-Allow-Origin' '*';
                add_header 'Access-Control-Max-Age' 1728000;
                add_header 'Content-Type' 'text/plain charset=UTF-8';
                add_header 'Content-Length' 0;
                return 204;
            }

            types {
                text/html html htm;
                application/dash+xml mpd;
                application/vnd.apple.mpegurl m3u8;
                video/mp2t ts;
            }

            index index.html;
            root /mnt/hls;
        }

        location /index.html {
            alias /web/index.html;
        }

    }
}
Enter fullscreen mode Exit fullscreen mode

Lastly create the ~/stream-service/web/index.html file with the next content:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>Live Stream</title>
    <link href="https://vjs.zencdn.net/7.8.4/video-js.css" rel="stylesheet" />
  </head>
  <body>
    <video id="my-video" class="video-js" controls preload="auto" width="640" height="360" data-setup="{}">
      <source src="/stream.m3u8" type="application/x-mpegURL" />
      <p class="vjs-no-js">
        To view this video please enable JavaScript, and consider upgrading to a web browser that
        <a href="https://videojs.com/html5-video-support/" target="_blank">supports HTML5 video</a>
      </p>
    </video>

    <script src="https://vjs.zencdn.net/7.8.4/video.js"></script>
  </body>
</html>
Enter fullscreen mode Exit fullscreen mode

Finally, change the web pages file permission. Otherwise nginx will not be able to serve it:

chmod 777 ~/stream-server/web/index.html
Enter fullscreen mode Exit fullscreen mode

Launching the services

With configuration files ready, in a terminal execute next instructions:

cd ~/stream-service
docker compose up
Enter fullscreen mode Exit fullscreen mode

The second command will take some time. It needs to download nginx image and start the service. Once ready you should see a text similar to Attaching to obs-nginx in the terminal.

Once everything is up and running, your streaming service will be accessible via the web interface (index.html). As users visit your webpage, they can view the content streamed through OBS and processed by your Nginx server.

Before being able to access the web page, you will need to know the ip address of your laptop. This can be obtained with the next instruction in the terminal:

ip address
Enter fullscreen mode Exit fullscreen mode

As we have docker installed you will see many networks. The network we are seeking it's typically named something like eth0 (for wired connections) or wlp2s0 or wlan0 (for wireless connections int laptop or raspberry pi). In my case it's wlp2s0 with the IP address 192.168.1.104. Now I can access to http://192.168.1.104/index.html, but the browser will just tell me that The media could not be found....

Configuring OBS for Streaming

Finally we need to configure OBS studio. Once we have the rest setup it is quite easy. We start by launching OBS stduio. If it's the first time you're opening OBS, you might see the Auto-Configuration Wizard. You can use this to set up your stream, or you can configure it manually in the settings. I will explain the second method.

In the OBS main window, find the 'Settings' button, usually located in the lower right corner. Click on it to open the settings window. Once the popup window opens, we select the stream tab (second in the left part of the window). And set the next settings:

Service: Custom
Server: rtmp://localhost/live
Stream Key: stream
Enter fullscreen mode Exit fullscreen mode

After entering these details, click 'Apply' and then 'OK' to save your streaming settings.

Now, you need to set up your video and audio sources in OBS. Before doing it you can open a media and start playing it. Afterwards, click the '+' button under the 'Sources' window and select the media you are playing. OBS automatically captures your primary desktop audio and microphone. You can adjust these and add additional audio sources in the 'Audio Mixer' section. Once your sources are set up, you're ready to go live. Just click the 'Start Streaming' button in OBS. Your content should now be streaming to your Nginx server and accessible through your configured web interface.

Now you can open in a devices browser the web address configured in the previous section and you should be able to play the media in your other device.

Final Notes

If you encounter issues or the stream isn't accessible on your smart TV, make sure your TV is connected to the same network as your streaming server. Also, check if any firewall or network settings are blocking access to the server. And still, if you're having difficulties or if there's something in this guide that isn't clear, please feel free to post your questions or concerns below. Your feedback is valuable and can help improve this guide. I'll try to provide advice or update the article to address common issues.

By following this guide, you've taken a big step in enhancing your home entertainment system. This DIY approach not only offers a customized viewing experience but also expands your technical skills. Enjoy your new streaming capability, and happy streaming!

Top comments (0)