diff --git a/MANIFEST b/MANIFEST
index ae192bb..2162982 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -1,6 +1,7 @@
.proverc
AUTHORS
bin/peertube-dl
+bin/peertube-dl-web.pl
cpanfile
lib/Peertube/DL/Downloaders.pm
lib/Peertube/DL/URLHandler.pm
@@ -9,6 +10,9 @@ lib/Peertube/DL/Utils.pm
LICENSE
Makefile.PL
MANIFEST This list of files
+public/css/index.css
+public/index.html
+public/js/peertube-dl-web.js
README.md
t/00-use_ok.t
t/downloaders/animeflv_example_response.html
diff --git a/bin/peertube-dl-web.pl b/bin/peertube-dl-web.pl
new file mode 100644
index 0000000..12a9913
--- /dev/null
+++ b/bin/peertube-dl-web.pl
@@ -0,0 +1,36 @@
+use Mojolicious::Lite -signatures;
+use Peertube::DL::URLHandler;
+
+get '/' => sub {
+ my $c = shift;
+ return $c->redirect_to('index.html');
+};
+
+post '/api' => sub {
+ my $c = shift;
+ my $url = $c->req->json->{url}
+ // ( return $c->render( text => 'Malformed request due missing url json parameter.', status => 400 ) );
+ my $render_returned;
+ eval { $render_returned = $c->render( json => Peertube::DL::URLHandler::getDownloadDataFromURL($url) ); };
+ if ($@) {
+ return $c->render( text => $@, status => 500 );
+ }
+ return $render_returned;
+};
+
+post '/proxy_to_get' => sub {
+ my $c = shift;
+ my $url = $c->req->json->{url}
+ // ( return $c->render( text => 'Malformed request due missing url json parameter.', status => 400 ) );
+ die "Not supported url" unless $url =~ s/^https:\/\///r =~ /^storage\.googleapis\.com/;
+ my $ua = Peertube::DL::URLHandler::generateUA();
+ return $c->render(
+ data => $ua->get($url)->decoded_content,
+ format => 'bin'
+ );
+};
+
+push @{ app->renderer->paths }, ('./templates');
+push @{ app->static->paths }, ('./public');
+app->start;
+
diff --git a/public/css/index.css b/public/css/index.css
new file mode 100644
index 0000000..9091cb3
--- /dev/null
+++ b/public/css/index.css
@@ -0,0 +1,39 @@
+body {
+ height: 90%;
+}
+
+a {
+ color: blue;
+}
+
+a:hover {
+ text-decoration: underline;
+}
+
+#video-container {
+ display: none;
+ background: white;
+ position: fixed;
+ top: 50%;
+ left: 50%;
+ height: 100%;
+ width: 100%;
+ transform: translate(-50%, -50%);
+ border: black 1px solid;
+}
+
+.video-container-bar {
+ display: flex;
+ justify-content: right;
+}
+
+#close-and-reset-video-container {
+ margin-top: 0.25rem;
+ margin-right: 0.25rem;
+ border: 1px solid black;
+}
+
+#close-and-reset-video-container:hover {
+ background: black;
+ color: white;
+}
diff --git a/public/index.html b/public/index.html
new file mode 100644
index 0000000..2db6b60
--- /dev/null
+++ b/public/index.html
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/public/js/peertube-dl-web.js b/public/js/peertube-dl-web.js
new file mode 100644
index 0000000..69390ae
--- /dev/null
+++ b/public/js/peertube-dl-web.js
@@ -0,0 +1,81 @@
+"use strict";
+
+let downloadFormButton;
+let videoContainer;
+let closeAndResetVideoContainer;
+let downloadFormUrl;
+let downloadVideo;
+let downloadForm;
+let video;
+
+function downloadFormButtonHandler(event) {
+ event.preventDefault();
+ getRealURL(downloadFormUrl.value).then( (response) => {
+ video.src = response.url;
+ videoContainer.style.display = 'block';
+ generateBlobVideo(response.url).then( blob => {
+ downloadVideo.href = URL.createObjectURL(blob);
+ downloadVideo.download = response.filename;
+ });
+ });
+}
+
+function downloadFormHandler(event) {
+ downloadFormButtonHandler(event);
+}
+
+async function generateBlobVideo(url) {
+ const blob = await fetch(url, {
+ mode: 'cors',
+ })
+ .then(res => res.blob())
+ .catch( err => generateBlobVideoByProxy(url) );
+ return blob;
+}
+
+async function generateBlobVideoByProxy(url) {
+ const blob = await fetch( '/proxy_to_get', {
+ method: 'POST',
+ mode: 'cors',
+ cache: 'no-cache',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify({url: url}),
+ }
+ ).then(res => res.blob());
+ return blob;
+ }
+
+async function getRealURL(url) {
+ const response = await fetch('/api', {
+ method: 'POST',
+ mode: 'cors',
+ cache: 'no-cache',
+ headers: {
+ 'Content-Type': 'application/json'
+ },
+ body: JSON.stringify({url: url}),
+ });
+ return response.json();
+}
+
+function closeAndResetVideoContainerHandler(event) {
+ event.preventDefault();
+ videoContainer.style.display = 'none';
+}
+
+window.addEventListener('load', (event) => {
+ downloadFormButton = document.querySelector('#download-form-button');
+ downloadForm = document.querySelector('#download-form');
+ videoContainer = document.querySelector('#video-container');
+ video = document.querySelector('#video');
+ downloadFormUrl = document.querySelector('#download-form-url');
+ downloadVideo = document.querySelector('#download-video');
+ closeAndResetVideoContainer = document.querySelector('#close-and-reset-video-container');
+ downloadFormButton.addEventListener('click', downloadFormButtonHandler);
+ downloadForm.addEventListener('submit', downloadFormHandler);
+ closeAndResetVideoContainer.addEventListener('click', closeAndResetVideoContainerHandler);
+});
+
+
diff --git a/t/downloaders/gocdn.t b/t/downloaders/gocdn.t
index 1d02317..04fb151 100644
--- a/t/downloaders/gocdn.t
+++ b/t/downloaders/gocdn.t
@@ -32,6 +32,7 @@ use JSON;
get => sub {
my $self = shift;
my $url = shift;
+ say STDERR $url;
$gocdn_url = $url;
return $gocdn_response;
}