How to keep your Youtube stream live! This trick is a must have!
Tags: rtsp, powershell, docker
Published: 2023-05-27 04:37:36

---
title: How to keep your Youtube stream live! This trick is a must have!
published: true
tags: RTSP, PowerShell, Docker
canonical_url: https://blog.bajonczak.com/how-to-prevent-youtube-livestream-to-be-stopped/
---

 ![How to keep your Youtube stream live!](https://images.unsplash.com/photo-1485846234645-a62644f84728?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wxMTc3M3wwfDF8c2VhcmNofDF8fG1vdmllfGVufDB8fHx8MTY4NTEyOTQ0NXww&ixlib=rb-4.0.3&q=80&w=2000)

In my last post, I show you how easy it is to forward a livestream to youtube from your local camera.

# The problem

Actually Youtube will stop your stream when there are no viewers. That's Ok, but when I stream I don't awaiting massive viewers.

# The idea

The idea is that I want to simulate a viewer, so I must download the video. After a little bit of googleing around (with bing) in the internet I found the [youtube-dl](http://ytdl-org.github.io/youtube-dl/?ref=blog.bajonczak.com) toolkit. This is a small shellscript that will take the url from your youtube video link an download it.

movieyou can just run the follwing command, to start download the video

```
youtube-dl YOUR_YOUTUBE_URL
```

But we have a livestream, so it will not stop at a given amount of time. So I must use a trick and pass the output stream to ffmpeg. In this I control the time to "view".

So I created a minimal script for this and it will end in this

```
YOUTUBE_STREAM_URL=myurl
DURATION_IN_SECONDS=5
DURATION_IN_SECONDS_TO_WAIT=120
echo "YOUTUBE_STREAM_URL=$YOUTUBE_STREAM_URL"
echo "DURATION_IN_SECONDS=$DURATION_IN_SECONDS"
echo "DURATION_IN_SECONDS_TO_WAIT=$DURATION_IN_SECONDS_TO_WAIT"

while :
do
  echo "Downloading video for $RECORD_TIME_IN_SECONDS seconds"
  # option -f 93 is for 360p stream
  URL=$(youtube-dl -g -f 93 $YOUTUBE_STREAM_URL)
  echo "Stream internal address(es): $URL"
  # Pass the stream to ffmpeg
  echo "$URL" | xargs -n 1 -I {} ffmpeg -t $RECORD_TIME_IN_SECONDS -i "{}" -f null -
  echo "Waiting for 10 minutes to restart the stream"
  sleep $DURATION_IN_SECONDS_TO_WAIT
```

This script will take myurl and "view" it for 5 seconds.  After this, it waits for 2 minutes and does it again every time. So it will simulate a recurring viewer.

# Dockerize it

Yep I want to do it on my homeserver and headless. I created a script file for the entry point and passing parameters into it. With this I can control the behaviour of the script. My final script looks like this

```
#!/bin/sh

if ["$#" -ne 3]; then
  >&2 echo "Required arguments: YOUTUBE_STREAM_URL DURATION_IN_SECONDS DURATION_IN_SECONDS_TO_WAIT"
  exit 1
fi

# -f 93 is for 360p stream
YOUTUBE_STREAM_URL=$1
DURATION_IN_SECONDS=$2
DURATION_IN_SECONDS_TO_WAIT=$3
echo "YOUTUBE_STREAM_URL=$YOUTUBE_STREAM_URL"
echo "DURATION_IN_SECONDS=$DURATION_IN_SECONDS"
echo "DURATION_IN_SECONDS_TO_WAIT=$DURATION_IN_SECONDS_TO_WAIT"

while :
do
  echo "Downloading video for 5 seconds"
  URL=$(youtube-dl -g -f 93 $YOUTUBE_STREAM_URL)
  echo "Stream internal address(es): $URL"
  echo "$URL" | xargs -n 1 -I {} ffmpeg -t $DURATION_IN_SECONDS -i "{}" -f null -
  echo "Waiting for 1 minute"
  sleep 60
done
```

I saved it as entrypoint.sh and put it beside a Dockerfiler with the following conten

```
# Usage 
# docker run youtube-stream-download https://youtube.com/live/h4j-dpvDWXY
FROM jrottenberg/ffmpeg
#MAINTAINER Sascha Bajonczak <xbeejayx@hotmail.com>
RUN apt-get update && apt-get install -y wget python && \
    ## Get the youtube downloader toolkit (ignore invalid certificate)
    wget https://yt-dl.org/downloads/latest/youtube-dl --no-check-certificate -O /usr/local/bin/youtube-dl && \
    chmod a+rx /usr/local/bin/youtube-dl && \
    rm -rf /var/lib/apt/lists/* /var/cache/apt

# Adding the entry point script
ADD entrypoint.sh /entrypoint.sh
# Pass parameters to the entrypoint script
ENTRYPOINT /entrypoint.sh $@
```

This dockerfile takes the ffmpeg base image and download the youtube download and install this in the image itself. After this it will add the script into the root filesystem and set this as entrypoint when the image will be started.

Now we can build it in the directory with the following command

```
docker build -t yourimagename . 
```

# Testrun

After building the container image I test the container and start it

```
docker run --restart=always -v /etc/localtime:/etc/localtime yourimagename -- https://youtube.com/live/STREAMID 5
```

This will pass the current time to the image and get the stream and also the seconds of time to record.  Inside the container the output will be look like this

```
Downloading video for 5 seconds
WARNING: Assuming --restrict-filenames since file system encoding cannot encode all characters. Set the LC_ALL environment variable to fix this.
ERROR: Unable to extract uploader id; please report this issue on https://yt-dl.org/bug . Make sure you are using the latest version; type youtube-dl -U to update. Be sure to call youtube-dl with the --verbose flag and include its complete output.
Stream internal address(es): 
Waiting for 1 minute
Downloading video for 5 seconds
WARNING: Assuming --restrict-filenames since file system encoding cannot encode all characters. Set the LC_ALL environment variable to fix this.
ERROR: Unable to extract uploader id; please report this issue on https://yt-dl.org/bug . Make sure you are using the latest version; type youtube-dl -U to update. Be sure to call youtube-dl with the --verbose flag and include its complete output.
Stream internal address(es): 
Waiting for 1 minute
Downloading video for 5 seconds
WARNING: Assuming --restrict-filenames since file system encoding cannot encode all characters. Set the LC_ALL environment variable to fix this.
ERROR: Unable to extract uploader id; please report this issue on https://yt-dl.org/bug . Make sure you are using the latest version; type youtube-dl -U to update. Be sure to call youtube-dl with the --verbose flag and include its complete output.
Stream internal address(es): 
Waiting for 1 minute
```

You can safetly ignore the error, because it is an internal error when they want to get the uploader\_id metadata. But we don't need it.

I created a docker container in the docker hub so you can then use it directly with this command

```
docker run -it --restart=always -v /etc/localtime:/etc/localtime stream.downloader -- https://youtube.com/live/0qPRKqRp-ys 5 120
```

It will fetch the stream from [https://youtube.com/live/0qPRKqRp-ys](https://youtube.com/live/0qPRKqRp-ys?ref=blog.bajonczak.com) for 5 seconds and wait 120 seconds for the next iteration.

# Conclusion

So you can now prevent the abortion of your stream, while you "view" it in a time of manner. So this is for me a little help, that will keep my stream ongoing. But unfortunaly ... my cam is broken. But hey, the next cam will arrive soon then I will update this post with the correct video URL .