tvheadend, fzf and mpv
by manu
I wanted to have an easy way to fuzzy find the channel I’d like to watch from my tvheadend’s playlist. After some chit chat with Claude AI I got exactly what I wanted: A fuzzy finder for my playlist, while still being able to zap to the prev/next channel. tvheadend + fzf + mpv = ❤️
#!/usr/bin/env python3
import sys
import subprocess
import re
import os
from pathlib import Path
def parse_m3u(content):
channels = []
current_name = None
for line in content.split('\n'):
if line.startswith('#EXTINF:'):
match = re.search(r',[^,]*$', line)
if match:
current_name = match.group()[1:]
elif line.startswith('http'):
if current_name:
channels.append((current_name, line.strip()))
current_name = None
return channels
def main():
playlist_path = str(Path.home() / "docs" / "playlist")
# Read and parse the M3U content
content = open(playlist_path).read()
channels = parse_m3u(content)
# Prepare channel names for fzf
channel_names = '\n'.join(name for name, _ in channels)
try:
# Run fzf with --reverse option
fzf = subprocess.Popen(['fzf', '--reverse'],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
text=True)
selected, _ = fzf.communicate(channel_names)
# Find the index of the selected channel
selected = selected.strip()
for index, (name, _) in enumerate(channels):
if name == selected:
# Launch mpv with the original playlist file
subprocess.run([
'mpv',
f'--playlist-start={index}',
f'--playlist={playlist_path}'
], env=dict(os.environ, DISPLAY=':0'))
break
except KeyboardInterrupt:
sys.exit(0)
if __name__ == "__main__":
main()