So I wrote a PHP script that will turn any RSS feed into an M3U file and an EPG file compatible with any IPTV application. I'm currently using this with TiviMate. In this example below, you'll see that I am pulling the RSS feeds from Democracy Now! and various other YouTube feeds using a combination of Podsync and ShiftRSS. After about two days of testing, I think I finally have it working flawlessly. I'll explain how to use it after I post the necessary code for the files.
You'll need to create a file named rss.php in any directory containing the following code:
<?php
$url = "http://" . $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"];
$paths = explode("/", $url);
$paths = str_replace("-"," ",$paths);
// print_r($paths);
$rss_array = array(
'https://democracynow.org/podcast-video.xml',
'https://podsync.net/1QPr',
'https://siftrss.com/f/d08JgNM5V3',
'https://siftrss.com/f/LbQX1zVA6z0',
'https://podsync.net/WQ2O',
'https://podsync.net/hH351ceab',
'https://podsync.net/IbukRyeEb'
);
global $limit,$startTime,$endTime,$channel,$thumbnail,$title,$description,$pubDate,$date,$url;
$limit = 2;
$startTime = date("YmdGis O",strtotime("-1 day"));
$endTime = date("YmdGis O",strtotime("+1 day"));
if ($paths[5] == "epg") {
header("Content-type: text/xml");
print "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
print "<!DOCTYPE tv SYSTEM \"xmltv.dtd\">";
print "<tv date=\"".date("YmdGis 0")."\" source-info-name=\"RSS EPG\" source-info-url=\"".$url."\">";
} else {
header("Content-type: text/m3u");
print "#EXTM3U"."\n\n";
}
for ($i=0; $i<count($rss_array); $i++ ) {
// if(++$i > $limit) break;
$rssfeed = simplexml_load_file($rss_array[$i]);
foreach ($rssfeed->channel as $channel) {
// $podcast = $channel->title;
$thumbnail = $channel->image->url;
$channel = str_ireplace(',','',$channel->title);
}
$num = 0;
foreach ($rssfeed->channel->item as $item) {
$title = $item->title;
$titleM3U = str_ireplace(',','',$title);
$titleEPG = preg_replace('/&(?!#?[a-z0-9]+;)/', '&', filter_var(str_ireplace('/,"+;)/','',$title), FILTER_SANITIZE_STRING, FILTER_SANITIZE_EMAIL));
$description = $item->description;
$description = preg_replace('/&(?!#?[a-z0-9]+;)/', '&', filter_var(str_ireplace('','',$description), FILTER_SANITIZE_STRING, FILTER_SANITIZE_EMAIL));
$pubDate = strtotime($item->pubDate);
$date = date('Y-m-d', $pubDate);
$url = $item->enclosure[url];
$itemNum = $num++;
if ($paths[5] == "epg") {
print "<channel id=\"".$pubDate.$itemNum."\">";
print "<display-name>".$channel."</display-name>";
print "</channel>";
print "<programme start=\"".$startTime."\" stop=\"".$endTime."\" channel=\"".$pubDate.$itemNum."\">";
print "<title lang=\"en\">".$titleEPG."</title>";
print "<desc lang=\"en\">".$description."</desc>";
print "</programme>";
// print "\n";
} else {
print "#EXTINF:-1 ";
print "tvg-logo=\"".$thumbnail."\" ";
print "epg-id=\"".$pubDate.$itemNum."\" ";
print "tvg-id=\"".$pubDate.$itemNum."\" ";
print "epg-url=\"".$url."/epg\" ";
print "tvg-url=\"".$url."/epg\" ";
print "group-title=\"📺 ".$channel."\",".$date." | ".$titleM3U;
print "\n";
print $url."\n\n";
}
}
}
if ($paths[5] == "epg") {
print "</tv>";
}
?>
You'll also need a file named .htaccess in the same directory containing the following code:
#Prevent viewing of .htaccess file
<Files .htaccess>
order allow,deny
deny from all
</Files>
#Prevent directory listings
Options All -Indexes
#RewriteEngine
Options +FollowSymLinks
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteCond %{SERVER_PORT} 443
RewriteRule ^/?$ http://%{SERVER_NAME}/ [R=301,L]
## REWRITE BROKEN LINKS ##
RewriteCond %{SERVER_PORT} 80
RewriteCond %{REQUEST_URI} !^/index\.php
RewriteCond %{REQUEST_URI} (/[^.]*|\.(php|html?|feed|pdf|raw))$ [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* index.php [L]
## REMOVE .PHP EXTENSION ##
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php
# REWRITE SPACES AND +
RewriteRule ^([^\ ]*)\ (.*)$ $1-$2 [E=rspace:yes,N]
RewriteCond %{ENV:rspace} yes
RewriteRule (.*) http://%{HTTP_HOST}$1 [R=301,L]
Now using this is SUPER simple. Simply replace the values in the $rss_array = array( section while keeping in mind the convention of encapsulating the array. Now to use this simply point your IPTV application to http://{DOMAIN}/{DIRECTORY}/RSS for the M3U file and http://{DOMAIN}/{DIRECTORY}/RSS/EPG for the EPG file. That's it!
You can have as many RSS feeds as you want as long as your memory holds up. I can't imagine this script crashing due to memory issues. However, it is a concern and something I intend to work on as I flesh this out into a prettier and easier to use setup.
With that said, please don't judge the code. I know it's ugly AF. I did this as fast as possible as more of a proof of concept and a test of utility and it isn't ready to publish to GitHub yet. I am working on a full suite of M3U/EPG solutions using PHP at the moment. I'm publishing this here to get feedback from other developers in this IPTV community. So if you have a suggestion or see something wrong, please hit me up!
Thanks, and I hope this helps someone out.