From 0e482d7156494a2ee87a07956ccca71cf9973ffc Mon Sep 17 00:00:00 2001
From: Tomasz Maciej Nowak <tomek_n@o2.pl>
Date: Mon, 25 Mar 2019 17:10:06 +0100
Subject: [PATCH 4/4] Add ability to play stream by external media player

It's based on vlc.ecpp. This implementation adds pink play button, which
serves playlist with stream link, playable by majority of media players.
Should work with every browser allowing to open files instead of only
downloading them.
---
 live/img/playlist.png    | Bin 0 -> 748 bytes
 pages/Makefile           |   3 +-
 pages/multischedule.ecpp |   1 +
 pages/pageelems.ecpp     |  29 ++++++++++++++++-
 pages/playlist.ecpp      |  66 +++++++++++++++++++++++++++++++++++++++
 pages/recordings.ecpp    |   1 +
 pages/schedule.ecpp      |   1 +
 po/cs_CZ.po              |   6 ++++
 po/de_DE.po              |   6 ++++
 po/es_ES.po              |   6 ++++
 po/fi_FI.po              |   6 ++++
 po/fr_FR.po              |   6 ++++
 po/it_IT.po              |   6 ++++
 po/lt_LT.po              |   6 ++++
 po/nl_NL.po              |   6 ++++
 po/pl_PL.po              |   6 ++++
 po/ru_RU.po              |   6 ++++
 po/sk_SK.po              |   6 ++++
 po/sv_SE.po              |   6 ++++
 19 files changed, 171 insertions(+), 2 deletions(-)
 create mode 100644 live/img/playlist.png
 create mode 100644 pages/playlist.ecpp

diff --git a/live/img/playlist.png b/live/img/playlist.png
new file mode 100644
index 0000000000000000000000000000000000000000..c197427604a92a19ba70bfa7827778163cbeab8e
GIT binary patch
diff --git a/pages/Makefile b/pages/Makefile
index ae0710e..a0d1ada 100644
--- a/pages/Makefile
+++ b/pages/Makefile
@@ -15,7 +15,8 @@ OBJS := menu.o recordings.o schedule.o multischedule.o screenshot.o   \
         searchepg.o login.o ibox.o xmlresponse.o play_recording.o	\
         pause_recording.o stop_recording.o ffw_recording.o		\
         rwd_recording.o setup.o content.o epginfo.o timerconflicts.o  \
-        recstream.o users.o edit_user.o edit_recording.o osd.o
+        recstream.o users.o edit_user.o edit_recording.o osd.o	\
+        playlist.o
 SRCS := $(patsubst %.o,%.cpp,$(OBJS))
 ESRCS := $(patsubst %.o,%.ecpp,$(OBJS))
 ESRCS_DEPS := $(patsubst %.o,.%.edep,$(OBJS))
diff --git a/pages/multischedule.ecpp b/pages/multischedule.ecpp
index d06ac44..ad68236 100644
--- a/pages/multischedule.ecpp
+++ b/pages/multischedule.ecpp
@@ -414,6 +414,7 @@ std::vector<time_t>			times_start;
 	       <td> <div class="boxheader"> <div> <div><$ channel_names[channel] $> <# reply.sout() automatically escapes special characters to html entities #>
             <& pageelems.ajax_action_href action="switch_channel" tip=(tr("Switch to this channel.")) param=(channel_IDs[channel]) image="zap.png" alt="" &>
             <& pageelems.vlc_stream_channel channelId=(channel_IDs[channel]) &>
+            <& pageelems.m3u_playlist_channel channelId=(channel_IDs[channel]) &>
             </div></div> </div></td>
 	       <td class="time spacer"> &nbsp; </td>
 <%cpp>
diff --git a/pages/pageelems.ecpp b/pages/pageelems.ecpp
index 38c0d21..723f4ff 100644
--- a/pages/pageelems.ecpp
+++ b/pages/pageelems.ecpp
@@ -131,6 +131,32 @@ int update_status(1);
 </%def>
 
 
+<# ---------------------------------------------------------------------- #>
+
+<%def m3u_playlist_channel>
+<%args>
+	tChannelID channelId;
+</%args>
+<%cpp> if (LiveSetup().GetUseStreamdev() && LiveFeatures<features::streamdev_server>().Loaded()) { </%cpp><a href="playlist.m3u?channel=<$ channelId $>"><img src="<$ LiveSetup().GetThemedLink("img", "playlist.png") $>" alt="" <& tooltip.hint text=(tr("Stream this channel into media player.")) &>></img></a><%cpp> } </%cpp>
+</%def>
+
+<# ---------------------------------------------------------------------- #>
+
+<%def m3u_playlist_recording>
+<%args>
+	string recid;
+	string linkText;
+</%args>
+<%cpp>
+#if TNT_WATCHDOG_SILENCE
+{
+</%cpp><a href="playlist.m3u?recid=<$ recid $>"><img src="<$ LiveSetup().GetThemedLink("img", "playlist.png") $>" alt="" <& tooltip.hint text=(tr("Stream this recording into media player.")) &>></img> <$ linkText $></a>
+<%cpp>
+}
+#endif
+</%cpp>
+</%def>
+
 <# ---------------------------------------------------------------------- #>
 
 <%def event_timer>
@@ -285,6 +311,7 @@ int update_status(1);
 		if ((duration == 0) || (elapsed >= 0)) {
 </%cpp>
 	<& pageelems.vlc_stream_channel channelId=(channelId) &>
+	<& pageelems.m3u_playlist_channel channelId=(channelId) &>
 <%cpp>
 		}
 	if (eventId != 0) {
@@ -298,7 +325,7 @@ int update_status(1);
 		<td class="action leftcol <? lastCurrentChanel ? "bottomrow"?>"><& pageelems.event_timer epgid=(epgid) &></td>
 		<td class="action <? lastCurrentChanel ? "bottomrow"?>"><& pageelems.ajax_action_href action="switch_channel" tip=(tr("Switch to this channel.")) param=(channelId) image="zap.png" alt="" &></td>
 		<td class="action <? lastCurrentChanel ? "bottomrow"?>"><%cpp>if (LiveFeatures<features::epgsearch>().Recent() && eventId != 0) { </%cpp><a href="searchresults.html?searchplain=<$ StringUrlEncode(title) $>"><img src="<$ LiveSetup().GetThemedLink("img", "search.png") $>" alt="" <& tooltip.hint text=(tr("Search for repeats.")) &>></img></a><%cpp> } else { </%cpp><img src="img/transparent.png" width="16" height="16"><%cpp> } </%cpp></td>
-        <td class="action <? lastCurrentChanel ? "bottomrow"?>"><%cpp>if ((duration == 0)  || (elapsed > 0)) { </%cpp><& pageelems.vlc_stream_channel channelId=(channelId) &><%cpp> } else { </%cpp><img src="img/transparent.png" width="16" height="16"><%cpp> } </%cpp></td>
+        <td class="action <? lastCurrentChanel ? "bottomrow"?>"><%cpp>if ((duration == 0)  || (elapsed > 0)) { </%cpp><& pageelems.vlc_stream_channel channelId=(channelId) &><& pageelems.m3u_playlist_channel channelId=(channelId) &><%cpp> } else { </%cpp><img src="img/transparent.png" width="16" height="16"><%cpp> } </%cpp></td>
 		<td class="action <? lastCurrentChanel ? "bottomrow"?>">
 <%cpp>
 			if (eventId != 0) {
diff --git a/pages/playlist.ecpp b/pages/playlist.ecpp
new file mode 100644
index 0000000..b98e2cc
--- /dev/null
+++ b/pages/playlist.ecpp
@@ -0,0 +1,66 @@
+<%pre>
+
+#include <setup.h>
+#include <tools.h>
+#include <users.h>
+
+using namespace std;
+using namespace vdrlive;
+
+</%pre>
+<%args>
+	tChannelID channel;
+	string recid;
+</%args>
+<%session scope="global">
+	bool logged_in(false);
+</%session>
+<%request scope="page">
+	cChannel* Channel;
+</%request>
+<%include>page_init.eh</%include>
+<%cpp>
+	if (!logged_in && LiveSetup().UseAuth()) return reply.redirect("login.html");
+	if (!cUser::CurrentUserHasRightTo(UR_STARTREPLAY))
+		throw HtmlError( tr("Sorry, no permission. Please contact your administrator!") );
+
+    // the availabilty of Channel signals that we will do live tv streaming.
+	Channel = 0;
+	if (recid.empty()) {
+#if VDRVERSNUM >= 20301
+		LOCK_CHANNELS_READ;
+		Channel = (cChannel *)Channels->GetByChannelID(channel);
+#else
+		ReadLock channelsLock(Channels);
+
+		if (!channelsLock) {
+			throw HtmlError(tr("Couldn't aquire access to channels, please try again later."));
+		}
+		Channel = Channels.GetByChannelID(channel);
+#endif
+		if (Channel == 0) {
+			throw HtmlError( tr("Couldn't find channel or no channels available. Maybe you mistyped your request?") );
+		}
+	}
+	string channelname = Channel->Name();
+	string server = request.getHost();
+	server = server.substr(0, server.rfind(':'));
+	string videourl;
+	reply.setContentType("application/vnd.apple.mpegurl");
+	if (Channel != 0) {
+		int streamdevPort = LiveSetup().GetStreamdevPort();
+		videourl = string("#EXTM3U\n#EXTINF:-1,") + channelname + "\nhttp://" + server + ":" + lexical_cast<string,int>(streamdevPort) + "/" + LiveSetup().GetStreamdevType() + "/" + *Channel->GetChannelID().ToString();
+	}
+	else {
+		videourl = string("#EXTM3U\n#EXTINF:-1\nhttp://") + server + ":" + lexical_cast<string,int>(LiveSetup().GetServerPort()) + "/recstream.html?recid=" + recid;
+	}
+</%cpp>
+<& playlist.m3u videourl=(videourl) &>
+<%include>page_exit.eh</%include>
+
+<%def m3u>
+<%args>
+	string videourl;
+</%args>
+<$ videourl $>
+</%def>
diff --git a/pages/recordings.ecpp b/pages/recordings.ecpp
index 9ef8a0a..1b2ce5c 100644
--- a/pages/recordings.ecpp
+++ b/pages/recordings.ecpp
@@ -332,6 +332,7 @@ for (recIter = recItems.begin(); recIter != recItems.end(); ++recIter) {
 </%args>
 <& pageelems.ajax_action_href action="play_recording" param=(id) tip=(tr("play this recording.")) image="play.png" alt="" &>
 <& pageelems.vlc_stream_recording recid=(id) &>
+<& pageelems.m3u_playlist_recording recid=(id) &>
 <& pageelems.imdb_info_href title=(title) &>
 <& recordings.edit_rec id=(id) &>
 <& recordings.del_rec id=(id) &>
diff --git a/pages/schedule.ecpp b/pages/schedule.ecpp
index 7321f3c..5a1dc34 100644
--- a/pages/schedule.ecpp
+++ b/pages/schedule.ecpp
@@ -176,6 +176,7 @@ if (!logged_in && LiveSetup().UseAuth()) return reply.redirect("login.html");
      <& channels_widget name=("channel") selected=(Channel ? *Channel->GetChannelID().ToString() : "") onchange=("document.forms.channels.submit()") &>
      <& pageelems.ajax_action_href action="switch_channel" tip=(tr("Switch to this channel.")) param=(Channel->GetChannelID()) image="zap.png" alt="" &>
      <& pageelems.vlc_stream_channel channelId=(Channel->GetChannelID()) &>
+     <& pageelems.m3u_playlist_channel channelId=(Channel->GetChannelID()) &>
    </span>
 </form>
 </%def>
diff --git a/po/cs_CZ.po b/po/cs_CZ.po
index 6bc0f8d..a33e76c 100644
--- a/po/cs_CZ.po
+++ b/po/cs_CZ.po
@@ -518,6 +518,12 @@ msgstr "Přehrávej v prohlížeči"
 msgid "Stream this recording into browser."
 msgstr "Přehrávej tuto nahrávku v prohlížeči."
 
+msgid "Stream this channel into media player."
+msgstr ""
+
+msgid "Stream this recording into media player."
+msgstr ""
+
 msgid "Record this"
 msgstr "Nahrát"
 
diff --git a/po/de_DE.po b/po/de_DE.po
index 27a6342..427cc3b 100644
--- a/po/de_DE.po
+++ b/po/de_DE.po
@@ -514,6 +514,12 @@ msgstr "Sendung im Browser anzeigen."
 msgid "Stream this recording into browser."
 msgstr "Aufnahme im Browser anzeigen."
 
+msgid "Stream this channel into media player."
+msgstr ""
+
+msgid "Stream this recording into media player."
+msgstr ""
+
 msgid "Record this"
 msgstr "Diese Sendung aufnehmen"
 
diff --git a/po/es_ES.po b/po/es_ES.po
index 900459b..2d71f3c 100644
--- a/po/es_ES.po
+++ b/po/es_ES.po
@@ -512,6 +512,12 @@ msgstr "Reproduce este canal en el navegador"
 msgid "Stream this recording into browser."
 msgstr "Reproduce esta grabaci�n en el navegador"
 
+msgid "Stream this channel into media player."
+msgstr ""
+
+msgid "Stream this recording into media player."
+msgstr ""
+
 msgid "Record this"
 msgstr "Grabar esto"
 
diff --git a/po/fi_FI.po b/po/fi_FI.po
index 16f3277..ebb36b1 100644
--- a/po/fi_FI.po
+++ b/po/fi_FI.po
@@ -512,6 +512,12 @@ msgstr "Aloita kanavan suoratoisto"
 msgid "Stream this recording into browser."
 msgstr "Aloita tallenteen suoratoisto"
 
+msgid "Stream this channel into media player."
+msgstr ""
+
+msgid "Stream this recording into media player."
+msgstr ""
+
 msgid "Record this"
 msgstr "Tallenna ohjelma"
 
diff --git a/po/fr_FR.po b/po/fr_FR.po
index 5edd5c5..1f4a5b8 100644
--- a/po/fr_FR.po
+++ b/po/fr_FR.po
@@ -523,6 +523,12 @@ msgstr "Diffusez cette cha
 msgid "Stream this recording into browser."
 msgstr "Diffusez cette cha�ne vers le navigateur."
 
+msgid "Stream this channel into media player."
+msgstr ""
+
+msgid "Stream this recording into media player."
+msgstr ""
+
 msgid "Record this"
 msgstr "Enregistrer cette �mission"
 
diff --git a/po/it_IT.po b/po/it_IT.po
index 521140c..ea5c1b6 100644
--- a/po/it_IT.po
+++ b/po/it_IT.po
@@ -518,6 +518,12 @@ msgstr "Trasmetti questo canale nel browser"
 msgid "Stream this recording into browser."
 msgstr "Trasmetti questa registrazione nel browser"
 
+msgid "Stream this channel into media player."
+msgstr ""
+
+msgid "Stream this recording into media player."
+msgstr ""
+
 msgid "Record this"
 msgstr "Registra questa trasmissione"
 
diff --git a/po/lt_LT.po b/po/lt_LT.po
index 4600dd5..ce93471 100644
--- a/po/lt_LT.po
+++ b/po/lt_LT.po
@@ -513,6 +513,12 @@ msgstr "Transliuoti šį kanalą į naršyklę."
 msgid "Stream this recording into browser."
 msgstr "Transliuoti šį įrašą į naršyklę."
 
+msgid "Stream this channel into media player."
+msgstr ""
+
+msgid "Stream this recording into media player."
+msgstr ""
+
 msgid "Record this"
 msgstr "Įrašyti"
 
diff --git a/po/nl_NL.po b/po/nl_NL.po
index 147d7e7..14b8be4 100644
--- a/po/nl_NL.po
+++ b/po/nl_NL.po
@@ -521,6 +521,12 @@ msgstr ""
 msgid "Stream this recording into browser."
 msgstr ""
 
+msgid "Stream this channel into media player."
+msgstr ""
+
+msgid "Stream this recording into media player."
+msgstr ""
+
 msgid "Record this"
 msgstr ""
 
diff --git a/po/pl_PL.po b/po/pl_PL.po
index 88010d3..99470de 100644
--- a/po/pl_PL.po
+++ b/po/pl_PL.po
@@ -513,6 +513,12 @@ msgstr "Oglądaj kanał w przeglądarce"
 msgid "Stream this recording into browser."
 msgstr "Oglądaj nagranie w przeglądarce"
 
+msgid "Stream this channel into media player."
+msgstr "Oglądaj kanał w odtwarzaczu multimediów"
+
+msgid "Stream this recording into media player."
+msgstr "Oglądaj nagranie w odtwarzaczu multimediów"
+
 msgid "Record this"
 msgstr "Nagraj"
 
diff --git a/po/ru_RU.po b/po/ru_RU.po
index 657666c..6984829 100644
--- a/po/ru_RU.po
+++ b/po/ru_RU.po
@@ -512,6 +512,12 @@ msgstr "Стриминг этого канала в браузер."
 msgid "Stream this recording into browser."
 msgstr "Стриминг этой записи в браузер."
 
+msgid "Stream this channel into media player."
+msgstr ""
+
+msgid "Stream this recording into media player."
+msgstr ""
+
 msgid "Record this"
 msgstr "Запись."
 
diff --git a/po/sk_SK.po b/po/sk_SK.po
index 2a30b1e..3b87878 100644
--- a/po/sk_SK.po
+++ b/po/sk_SK.po
@@ -513,6 +513,12 @@ msgstr "Prezera
 msgid "Stream this recording into browser."
 msgstr "Prezera� t�to nahr�vku v prehliada�i."
 
+msgid "Stream this channel into media player."
+msgstr ""
+
+msgid "Stream this recording into media player."
+msgstr ""
+
 msgid "Record this"
 msgstr "Nahra�"
 
diff --git a/po/sv_SE.po b/po/sv_SE.po
index 475d6fe..a127134 100644
--- a/po/sv_SE.po
+++ b/po/sv_SE.po
@@ -512,6 +512,12 @@ msgstr "Strömma denna kanal till webläsaren"
 msgid "Stream this recording into browser."
 msgstr "Strömma denna inspelning till webläsaren."
 
+msgid "Stream this channel into media player."
+msgstr ""
+
+msgid "Stream this recording into media player."
+msgstr ""
+
 msgid "Record this"
 msgstr "Spela in detta."
 
-- 
2.21.0

