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

Embedded video player #297

Merged
merged 2 commits into from
Dec 28, 2022
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
5 changes: 5 additions & 0 deletions config/root/etc/nginx/nginx.conf
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,11 @@ http {
proxy_connect_timeout 10;
}

# File dwnload and streaming
location /media-data/ {
internal;
alias /downloads/;
}
}

}
25 changes: 25 additions & 0 deletions tubesync/sync/migrations/0013_fix_elative_media_file.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Generated by Django 3.2.12 on 2022-04-06 06:19

from django.conf import settings
from django.db import migrations, models


def fix_media_file(apps, schema_editor):
Media = apps.get_model('sync', 'Media')
for media in Media.objects.filter(downloaded=True):
download_dir = str(settings.DOWNLOAD_ROOT)

if media.media_file.name.startswith(download_dir):
media.media_file.name = media.media_file.name[len(download_dir) + 1:]
media.save()


class Migration(migrations.Migration):

dependencies = [
('sync', '0012_alter_media_downloaded_format'),
]

operations = [
migrations.RunPython(fix_media_file)
]
10 changes: 7 additions & 3 deletions tubesync/sync/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
from .mediaservers import PlexMediaServer


media_file_storage = FileSystemStorage(location=str(settings.DOWNLOAD_ROOT))
media_file_storage = FileSystemStorage(location=str(settings.DOWNLOAD_ROOT), base_url='/media-data/')


class Source(models.Model):
Expand Down Expand Up @@ -392,10 +392,14 @@ def format_summary(self):
@property
def directory_path(self):
download_dir = Path(media_file_storage.location)
return download_dir / self.type_directory_path

@property
def type_directory_path(self):
if self.source_resolution == self.SOURCE_RESOLUTION_AUDIO:
return download_dir / settings.DOWNLOAD_AUDIO_DIR / self.directory
return Path(settings.DOWNLOAD_AUDIO_DIR) / self.directory
else:
return download_dir / settings.DOWNLOAD_VIDEO_DIR / self.directory
return Path(settings.DOWNLOAD_VIDEO_DIR) / self.directory

def make_directory(self):
return os.makedirs(self.directory_path, exist_ok=True)
Expand Down
2 changes: 1 addition & 1 deletion tubesync/sync/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,7 @@ def download_media(media_id):
log.info(f'Successfully downloaded media: {media} (UUID: {media.pk}) to: '
f'"{filepath}"')
# Link the media file to the object and update info about the download
media.media_file.name = str(filepath)
media.media_file.name = str(media.source.type_directory_path / media.filename)
media.downloaded = True
media.download_date = timezone.now()
media.downloaded_filesize = os.path.getsize(filepath)
Expand Down
6 changes: 6 additions & 0 deletions tubesync/sync/templates/sync/media-item.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ <h1 class="truncate">Media <strong>{{ media.key }}</strong> {{ download_state_ic
{% if media.title %}<h2 class="truncate"><strong>{{ media.title }}</strong></h2>{% endif %}
<p class="truncate"><strong><a href="{{ media.url }}" target="_blank"><i class="fas fa-link"></i> {{ media.url }}</a></strong></p>
<p class="truncate">Downloading to: <strong>{{ media.source.directory_path }}</strong></p>
{% if download_state == 'downloaded' %}
<video controls style="width: 100%">
<source src="{% url 'sync:media-content' pk=media.pk %}">
</video>
<p class="truncate"><a href="{% url 'sync:media-content' pk=media.pk %}" download="{{ media.filename }}">Download</a></p>
{% endif %}
</div>
</div>
{% if not media.can_download %}{% include 'errorbox.html' with message='Media cannot be downloaded because it has no formats which match the source requirements.' %}{% endif %}
Expand Down
6 changes: 5 additions & 1 deletion tubesync/sync/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from .views import (DashboardView, SourcesView, ValidateSourceView, AddSourceView,
SourceView, UpdateSourceView, DeleteSourceView, MediaView,
MediaThumbView, MediaItemView, MediaRedownloadView, MediaSkipView,
MediaEnableView, TasksView, CompletedTasksView, ResetTasks,
MediaEnableView, MediaContent, TasksView, CompletedTasksView, ResetTasks,
MediaServersView, AddMediaServerView, MediaServerView,
DeleteMediaServerView, UpdateMediaServerView)

Expand Down Expand Up @@ -70,6 +70,10 @@
MediaEnableView.as_view(),
name='enable-media'),

path('media-content/<uuid:pk>',
MediaContent.as_view(),
name='media-content'),

# Task URLs

path('tasks',
Expand Down
19 changes: 19 additions & 0 deletions tubesync/sync/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -686,6 +686,25 @@ def get_success_url(self):
return append_uri_params(url, {'message': 'enabled'})


class MediaContent(DetailView):
'''
Redirect to nginx to download the file
'''
model = Media

def __init__(self, *args, **kwargs):
self.object = None
super().__init__(*args, **kwargs)

def dispatch(self, request, *args, **kwargs):
self.object = self.get_object()

headers = {
'X-Accel-Redirect': self.object.media_file.url,
}
return HttpResponse(headers=headers)


class TasksView(ListView):
'''
A list of tasks queued to be completed. This is, for example, scraping for new
Expand Down