Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Configure Test RTMP URL to Event #31

Merged
merged 6 commits into from
Feb 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
.env*
.venv/
.vscode/
__pycache__/
db.sqlite3
.env*
muxy.db
static/
.venv/
6 changes: 5 additions & 1 deletion env.sample
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ TIME_ZONE=UTC

DB_PATH=./muxy.db

NGINX_RTMP_UPDATE_TIMEOUT=30
NGINX_RTMP_UPDATE_TIMEOUT=10

EMAIL_FROM=

DEFAULT_PUBLIC_RTMP_URL=rtmp://<insert_your_domain>/live
DEFAULT_RTMP_URL=rtmp://localhost/main
DEFAULT_TEST_RTMP_URL=rtmp://localhost/test
19 changes: 19 additions & 0 deletions events/migrations/0021_event_test_rtmp_url.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Generated by Django 3.1.14 on 2024-02-05 15:23

from django.db import migrations
import events.models


class Migration(migrations.Migration):

dependencies = [
('events', '0020_stream_tags'),
]

operations = [
migrations.AddField(
model_name='event',
name='test_rtmp_url',
field=events.models.RTMPURLField(blank=True, null=True),
),
]
29 changes: 29 additions & 0 deletions events/migrations/0022_auto_20240205_2058.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Generated by Django 3.1.14 on 2024-02-05 20:58

from django.db import migrations
import events.models


class Migration(migrations.Migration):

dependencies = [
('events', '0021_event_test_rtmp_url'),
]

operations = [
migrations.AlterField(
model_name='event',
name='public_rtmp_url',
field=events.models.RTMPURLField(blank=True, default=events.models.get_default_public_rtmp_url, null=True),
),
migrations.AlterField(
model_name='event',
name='rtmp_url',
field=events.models.RTMPURLField(blank=True, default=events.models.get_default_rtmp_url, null=True),
),
migrations.AlterField(
model_name='event',
name='test_rtmp_url',
field=events.models.RTMPURLField(blank=True, default=events.models.get_default_test_rtmp_url, null=True),
),
]
33 changes: 28 additions & 5 deletions events/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@

from autoslug import AutoSlugField
from django.conf import settings
from django.contrib.auth.models import User
from django.core import validators
from django.core.exceptions import ValidationError
from django.db import models
Expand Down Expand Up @@ -57,6 +56,18 @@ class Meta(AbstractAPIKey.Meta):
verbose_name_plural = "API keys"


def get_default_public_rtmp_url():
return settings.DEFAULT_PUBLIC_RTMP_URL


def get_default_rtmp_url():
return settings.DEFAULT_RTMP_URL


def get_default_test_rtmp_url():
return settings.DEFAULT_TEST_RTMP_URL


class Event(models.Model):
name = models.CharField(max_length=200)
slug = AutoSlugField(null=True, default=None, populate_from="name", unique="name")
Expand All @@ -66,8 +77,13 @@ class Event(models.Model):
ends_at = models.DateTimeField()
active = models.BooleanField(default=True)
preparation_time = models.PositiveIntegerField(default=5)
rtmp_url = RTMPURLField(blank=True, null=True)
public_rtmp_url = RTMPURLField(blank=True, null=True)
public_rtmp_url = RTMPURLField(
blank=True, null=True, default=get_default_public_rtmp_url
)
rtmp_url = RTMPURLField(blank=True, null=True, default=get_default_rtmp_url)
test_rtmp_url = RTMPURLField(
blank=True, null=True, default=get_default_test_rtmp_url
)
contact_email = models.EmailField(blank=True, null=True)

def __str__(self):
Expand All @@ -93,6 +109,11 @@ def resolved_rtmp_url(self):
if self.rtmp_url:
return resolve_url(self.rtmp_url)

@property
def resolved_test_rtmp_url(self):
if self.test_rtmp_url:
return resolve_url(self.test_rtmp_url)

@property
def duration(self):
if self.starts_at and self.ends_at:
Expand Down Expand Up @@ -230,12 +251,14 @@ def __str__(self):


class StreamArchiveURL(models.Model):
stream = models.ForeignKey(Stream, on_delete=models.CASCADE, related_name="archive_urls")
stream = models.ForeignKey(
Stream, on_delete=models.CASCADE, related_name="archive_urls"
)
url = models.URLField()
name = models.CharField(max_length=255, blank=True)

def __str__(self):
return self.url

class Meta:
unique_together = ("stream", "url")
unique_together = ("stream", "url")
4 changes: 2 additions & 2 deletions events/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -207,8 +207,8 @@ def test_update_stream_set_archive_urls(self):

data = {
"archive_urls": [
{ "url": "https://archive.org/foo", "name": "archive.org" },
{ "url": "https://youtube.com/foo", "name": "youtube.com" },
{"url": "https://archive.org/foo", "name": "archive.org"},
{"url": "https://youtube.com/foo", "name": "youtube.com"},
]
}
response = self.client.patch(
Expand Down
29 changes: 21 additions & 8 deletions events/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,24 +82,37 @@ def on_publish(request):

now = timezone.now()

# Check if stream is valid
# If stream is not valid (i.e. not preparing or inactive)
if not stream.is_valid_at(now):
print("[PUBLISH] Stream is not valid at %s" % (now))
return HttpResponseForbidden("Stream is not valid now")
# If event has a test RTMP URL, redirect to it
if stream.event.test_rtmp_url:
print(
"[PUBLISH] Stream is not valid now (%s). Redirect to Test RTMP URL."
% (now)
)
return RtmpRedirect(stream.resolved_test_rtmp_url)
else:
# Otherwise, deny the stream
print("[PUBLISH] Stream is not valid now (%s)" % (now))
return HttpResponseForbidden("Stream is not valid now")

# If event has a custom RTMP URL, redirect to it
if stream.event.rtmp_url:
if stream.is_preparing_at(now):
print(
"[PUBLISH] Stream is preparing and not active yet. Allow but do not redirect."
)
return HttpResponse("OK")
if stream.event.test_rtmp_url:
print(
"[PUBLISH] Stream is preparing and not active yet. Redirect to Test RTMP URL."
)
return RtmpRedirect(stream.resolved_test_rtmp_url)
else:
print("[PUBLISH] Stream is preparing and not active yet. Allow.")
return HttpResponse("OK")
else:
# Set the stream live
stream.live_at = now
stream.save()

print("[PUBLISH] Stream is active. Allow and redirect.")
print("[PUBLISH] Stream is active. Allow and redirect to custom RTMP URL.")
return RtmpRedirect(stream.resolved_rtmp_url)
else:
print("[PUBLISH] Stream is active. Allow.")
Expand Down
6 changes: 5 additions & 1 deletion muxy/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@
"PAGE_SIZE": 1000,
}

NGINX_RTMP_UPDATE_TIMEOUT = int(os.getenv("NGINX_RTMP_UPDATE_TIMEOUT", "30"))
NGINX_RTMP_UPDATE_TIMEOUT = int(os.getenv("NGINX_RTMP_UPDATE_TIMEOUT", "10"))

EMAIL_BACKEND = os.getenv(
"EMAIL_BACKEND", "django.core.mail.backends.console.EmailBackend"
Expand Down Expand Up @@ -200,3 +200,7 @@
CORS_ALLOW_HEADERS = list(default_headers) + [
STREAM_KEY_HEADER,
]

DEFAULT_PUBLIC_RTMP_URL = os.getenv("DEFAULT_PUBLIC_RTMP_URL")
DEFAULT_RTMP_URL = os.getenv("DEFAULT_RTMP_URL")
DEFAULT_TEST_RTMP_URL = os.getenv("DEFAULT_TEST_RTMP_URL")
Loading