Skip to content
Open
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
*.m3u
.DS_Store
*.pyc
!webapp/sample.m3u
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,16 @@ on Ubuntu/Debian `sudo apt-get install pyqt4-dev-tools`

![alt tag](screenshot/gui.png)

## How to use the Web App

The repository now includes a small Flask application that can display and play
generated playlists through a browser.

* `cd webapp`
* install the dependencies `pip install -r requirements.txt`
* run the application with `python app.py`
* open `http://localhost:5000` in your browser

## Compatibility

This program work on Window, Linux, Mac OSX and BSD. The only requirement is
Expand Down
58 changes: 58 additions & 0 deletions webapp/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
from flask import Flask, render_template, request, abort
import os

app = Flask(__name__)

# Directory that contains generated playlists
PLAYLIST_DIR = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'iptv', 'output')


def parse_m3u(path):
channels = []
name = None
with open(path, 'r', errors='ignore') as f:
for line in f:
line = line.strip()
if not line:
continue
if line.startswith('#EXTINF'):
parts = line.split(',', 1)
if len(parts) > 1:
name = parts[1].strip()
elif line.startswith('#'):
continue
else:
url = line
channels.append({'name': name or url, 'url': url})
name = None
return channels


@app.route('/')
def index():
if not os.path.isdir(PLAYLIST_DIR):
playlists = []
else:
playlists = [f for f in os.listdir(PLAYLIST_DIR) if f.endswith('.m3u') or f.endswith('.m3u8')]
return render_template('index.html', playlists=playlists)


@app.route('/playlist/<path:filename>')
def playlist(filename):
path = os.path.join(PLAYLIST_DIR, filename)
if not os.path.isfile(path):
abort(404)
channels = parse_m3u(path)
return render_template('playlist.html', playlist=filename, channels=channels)


@app.route('/play')
def play():
url = request.args.get('url')
if not url:
abort(404)
return render_template('player.html', url=url)


if __name__ == '__main__':
app.run(debug=True)
1 change: 1 addition & 0 deletions webapp/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Flask
3 changes: 3 additions & 0 deletions webapp/sample.m3u
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#EXTM3U
#EXTINF:-1,Sample Channel
https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8
17 changes: 17 additions & 0 deletions webapp/templates/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>IPTV Web App</title>
</head>
<body>
<h1>Available Playlists</h1>
<ul>
{% for p in playlists %}
<li><a href="{{ url_for('playlist', filename=p) }}">{{ p }}</a></li>
{% else %}
<li>No playlists found.</li>
{% endfor %}
</ul>
</body>
</html>
15 changes: 15 additions & 0 deletions webapp/templates/player.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Player</title>
</head>
<body>
<h1>Channel Player</h1>
<video id="video" width="640" controls autoplay>
<source src="{{ url }}" type="application/vnd.apple.mpegurl">
</video>
<p><a href="{{ url }}">Open stream directly</a></p>
<p><a href="{{ url_for('index') }}">Home</a></p>
</body>
</html>
16 changes: 16 additions & 0 deletions webapp/templates/playlist.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>{{ playlist }}</title>
</head>
<body>
<h1>{{ playlist }}</h1>
<ul>
{% for c in channels %}
<li><a href="{{ url_for('play') }}?url={{ c.url }}">{{ c.name }}</a></li>
{% endfor %}
</ul>
<p><a href="{{ url_for('index') }}">Back to playlists</a></p>
</body>
</html>