instance2 / app.py
ChandimaPrabath's picture
test player
f505705
raw
history blame
7.77 kB
from flask import Flask, jsonify, render_template, request, Response
import os
import json
import re
import urllib.parse
from threading import Thread
import uuid
from video import ffmpeg_stream
from indexer import indexer
from dotenv import load_dotenv
from tvdb import fetch_and_cache_json
load_dotenv()
INDEX_FILE = os.getenv("INDEX_FILE")
TOKEN = os.getenv("TOKEN")
REPO = os.getenv("REPO")
CACHE_DIR = os.getenv("CACHE_DIR")
if not os.path.exists(CACHE_DIR):
os.makedirs(CACHE_DIR)
indexer()
if not os.path.exists(INDEX_FILE):
raise FileNotFoundError(f"{INDEX_FILE} not found. Please make sure the file exists.")
with open(INDEX_FILE, 'r') as f:
file_structure = json.load(f)
def prefetch_metadata():
for item in file_structure:
if 'contents' in item:
for sub_item in item['contents']:
original_title = sub_item['path'].split('/')[-1]
media_type = 'series' if item['path'].startswith('tv') else 'movie'
title = original_title
year = None
match = re.search(r'\((\d{4})\)', original_title)
if match:
year_str = match.group(1)
if year_str.isdigit() and len(year_str) == 4:
title = original_title[:match.start()].strip()
year = int(year_str)
else:
parts = original_title.rsplit(' ', 1)
if len(parts) > 1 and parts[-1].isdigit() and len(parts[-1]) == 4:
title = parts[0].strip()
year = int(parts[-1])
fetch_and_cache_json(original_title, title, media_type, year)
def get_film_file_path(title):
decoded_title = urllib.parse.unquote(title)
normalized_title = decoded_title.split(' (')[0].strip()
for item in file_structure:
if item['path'].startswith('films'):
for sub_item in item['contents']:
sub_item_title = sub_item['path'].split('/')[-1]
normalized_sub_item_title = sub_item_title.split(' (')[0].strip()
if normalized_title == normalized_sub_item_title:
for file in sub_item['contents']:
if file['type'] == 'file':
return file['path']
return None
def get_tv_show_seasons(title):
seasons = []
for item in file_structure:
if item['path'].startswith('tv'):
for sub_item in item['contents']:
if sub_item['type'] == 'directory' and title in sub_item['path']:
for season in sub_item['contents']:
if season['type'] == 'directory':
episodes = []
for episode in season['contents']:
if episode['type'] == 'file':
episodes.append({
"title": episode['path'].split('/')[-1],
"path": episode['path']
})
seasons.append({
"season": season['path'].split('/')[-1],
"episodes": episodes
})
return seasons
return []
def start_prefetching():
prefetch_metadata()
def generate(file_url):
# Generate a unique stream ID
stream_id = str(uuid.uuid4())
output_dir = os.path.join(CACHE_DIR, "stream", stream_id)
# Ensure output directory exists
if not os.path.exists(output_dir):
os.makedirs(output_dir)
# Set up HLS streaming
token = TOKEN
output_path, process = ffmpeg_stream(file_url, token, output_dir=output_dir)
if output_path:
# Return the unique stream ID for later use
return stream_id
return None
thread = Thread(target=start_prefetching)
thread.daemon = True
thread.start()
app = Flask(__name__)
@app.route('/')
def home():
return render_template('index.html')
@app.route('/tvshow_player')
def tvshow_player():
return render_template('player.html')
@app.route('/film_player')
def film_player():
title = request.args.get('title')
if not title:
return "No film title provided", 400
return render_template('film_player.html', title=urllib.parse.unquote(title))
@app.route('/films')
def films():
return render_template('films.html')
@app.route('/api/films')
def list_films():
films = [item for item in file_structure if item['path'].startswith('films')]
return jsonify([sub_item for film in films for sub_item in film['contents']])
@app.route('/tv')
def tv_shows():
return render_template('tvshows.html')
@app.route('/api/tv')
def list_tv():
tv_shows = [item for item in file_structure if item['path'].startswith('tv')]
return jsonify([sub_item for show in tv_shows for sub_item in show['contents']])
@app.route('/api/film/<path:title>')
def film_page(title):
title = urllib.parse.unquote(title)
film_file_path = get_film_file_path(title)
if not film_file_path:
return jsonify({'error': 'Film not found'}), 404
json_cache_path = os.path.join(CACHE_DIR, f"{urllib.parse.quote(title)}.json")
if os.path.exists(json_cache_path):
with open(json_cache_path, 'r') as f:
metadata = json.load(f)
else:
return jsonify({'error': 'Metadata not found'}), 404
return jsonify({
'metadata': metadata,
'file_path': film_file_path
})
@app.route('/api/tv/<path:show_title>')
def tv_page(show_title):
show_title = urllib.parse.unquote(show_title)
seasons = get_tv_show_seasons(show_title)
if not seasons:
return jsonify({'error': 'TV show not found'}), 404
json_cache_path = os.path.join(CACHE_DIR, f"{urllib.parse.quote(show_title)}.json")
if os.path.exists(json_cache_path):
with open(json_cache_path, 'r') as f:
metadata = json.load(f)
else:
return jsonify({'error': 'Metadata not found'}), 404
return jsonify({
'metadata': metadata,
'seasons': seasons
})
@app.route('/get_metadata')
def get_metadata():
title = request.args.get('title')
if not title:
return jsonify({'error': 'No title provided'}), 400
json_cache_path = os.path.join(CACHE_DIR, f"{urllib.parse.quote(title)}.json")
if os.path.exists(json_cache_path):
with open(json_cache_path, 'r') as f:
data = json.load(f)
return jsonify(data)
return jsonify({'error': 'Metadata not found'}), 404
@app.route('/film/<path:title>')
def film_details(title):
return render_template('film_details_page.html', title=title)
@app.route('/api/stream')
def stream_video():
file_path = request.args.get('path')
if not file_path:
return "File path not provided", 400
file_url = f"https://huggingface.co/{REPO}/resolve/main/{file_path}"
stream_id = generate(file_url)
if stream_id:
# Return the UUID for the client to use
return jsonify({'stream_id': stream_id})
return "Streaming error", 500
@app.route('/stream/<stream_id>')
def stream_file(stream_id):
stream_dir = os.path.join(CACHE_DIR, "stream", stream_id)
playlist_path = os.path.join(stream_dir, 'output.m3u8')
if os.path.exists(playlist_path):
return Response(
open(playlist_path, 'rb').read(),
mimetype='application/vnd.apple.mpegurl'
)
return "Stream not found", 404
if __name__ == '__main__':
app.run(debug=True, host="0.0.0.0", port=7860)