1
0
Fork 0

mpv as a daemon for radio streaming

This commit is contained in:
Massaki Archambault 2018-11-07 23:52:35 -05:00
parent 290aa6a9df
commit 8c3112dda1
10 changed files with 158 additions and 4 deletions

View File

@ -105,6 +105,8 @@ bindsym $mod+Shift+q kill
bindsym $mod+Control+Return exec /bin/bash ~/.config/i3/rofi.bash
# start rofi-pass for password autotype
bindsym $mod+Shift+Return exec rofi-pass
# start rofi-radio
bindsym $mod+p exec ~/.config/i3/rofi-radio.py
# change focus
bindsym $mod+h focus left
@ -255,7 +257,7 @@ exec --no-startup-id /bin/dex -a
exec --no-startup-id /bin/bash ~/.config/i3/startup.bash
bar {
status_command i3status --config ~/.config/i3/i3status.conf
status_command i3status --config ~/.config/i3/i3status.conf | ~/.config/i3/wrapper.py
output primary
font pango:$font 10

View File

@ -12,6 +12,7 @@ general {
color_degraded = "#E2995C"
color_bad = "#B04C50"
output_format = "i3bar"
interval = 5
}

46
files/.config/i3/rofi-radio.py Executable file
View File

@ -0,0 +1,46 @@
#!/usr/bin/env python3
import json
import yaml
import os
import sys
from subprocess import Popen, PIPE, check_output, check_call
def mpv_ipc(*args):
try:
j = json.loads(check_output(['mpv-ipc'] + list(args)))
if j:
return j['data']
except:
pass
return ''
with open(os.path.expanduser("~/.local/share/playlists.yaml")) as y:
stations = yaml.load(y)
rofi_command = ['rofi', '-i', '-selected-row', '0', '-dmenu', '-p', 'mpv']
current_song = mpv_ipc('get_property_string', 'media-title')
if current_song:
rofi_command += ['-mesg', current_song]
commands = b"Play/Pause\nStop\nNext\nPrevious"
else:
commands = bytes('\n'.join([s["name"] for s in stations]), 'utf8')
rofi = Popen(rofi_command, stdout=PIPE, stdin=PIPE)
choice = rofi.communicate(input=commands)[0].decode('utf8').rstrip()
if current_song:
if choice == "Play/Pause":
mpv_ipc('cycle', 'pause')
elif choice == "Stop":
mpv_ipc('stop')
else:
s = [s for s in stations if s["name"] == choice]
if s:
mpv_ipc('loadfile', s[0]["loc"])
mpv_ipc('set_property_string', 'pause', 'no')
# force update of i3status
check_call('killall', '-USR1', 'i3status')

78
files/.config/i3/wrapper.py Executable file
View File

@ -0,0 +1,78 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# This script is a simple wrapper which prefixes each i3status line with custom
# information. It is a python reimplementation of:
# http://code.stapelberg.de/git/i3status/tree/contrib/wrapper.pl
#
# To use it, ensure your ~/.i3status.conf contains this line:
# output_format = "i3bar"
# in the 'general' section.
# Then, in your ~/.i3/config, use:
# status_command i3status | ~/i3status/contrib/wrapper.py
# In the 'bar' section.
#
# In its current version it will display the cpu frequency governor, but you
# are free to change it to display whatever you like, see the comment in the
# source code below.
#
# © 2012 Valentin Haenel <valentin.haenel@gmx.de>
#
# This program is free software. It comes without any warranty, to the extent
# permitted by applicable law. You can redistribute it and/or modify it under
# the terms of the Do What The Fuck You Want To Public License (WTFPL), Version
# 2, as published by Sam Hocevar. See http://sam.zoy.org/wtfpl/COPYING for more
# details.
import subprocess
import sys
import json
def get_song_name():
""" Get the name of the currently playing song """
try:
j = json.loads(subprocess.check_output(['mpv-ipc', 'get_property_string', 'media-title']))
if j['data']:
return '' + j['data']
except:
pass
return ''
def print_line(message):
""" Non-buffered printing to stdout. """
sys.stdout.write(message + '\n')
sys.stdout.flush()
def read_line():
""" Interrupted respecting reader for stdin. """
# try reading a line, removing any extra whitespace
try:
line = sys.stdin.readline().strip()
# i3status sends EOF, or an empty line
if not line:
sys.exit(3)
return line
# exit on ctrl-c
except KeyboardInterrupt:
sys.exit()
if __name__ == '__main__':
# Skip the first line which contains the version header.
print_line(read_line())
# The second line contains the start of the infinite array.
print_line(read_line())
while True:
line, prefix = read_line(), ''
# ignore comma at start of lines
if line.startswith(','):
line, prefix = line[1:], ','
j = json.loads(line)
# insert information into the start of the json, but could be anywhere
song_name = get_song_name()
if song_name:
j.insert(0, {'full_text' : '%s' % song_name, 'name' : 'music'})
# and echo back new encoded json
print_line(prefix+json.dumps(j))

View File

@ -1,10 +1,19 @@
profile=opengl-hq
# video
profile=gpu-hq
video-sync=display-resample
x11-bypass-compositor=yes
display-fps=60
interpolation
# audio
af=acompressor
# filter
scale=ewa_lanczossharp
cscale=ewa_lanczossharp
tscale=oversample
# extra
save-position-on-quit
no-sub
interpolation

View File

@ -0,0 +1,8 @@
[Unit]
Description=mpv - a media player
[Service]
ExecStart=/usr/bin/mpv --idle --input-ipc-server /tmp/mpv.sock
[Install]
WantedBy=default.target

View File

@ -2,7 +2,7 @@
exec 1<&-
system_services="cronie"
user_services="compton redshift"
user_services="compton redshift mpv"
if [[ "$1" == "start" ]]; then
for service in $system_services; do

4
files/.local/bin/mpv-ipc Executable file
View File

@ -0,0 +1,4 @@
#!/bin/bash
jq -nc --arg argv "$(echo "$@" | tr ' ' '\n')" '{ command: $argv | split("\n") }' | socat - /tmp/mpv.sock 2>/dev/null

View File

@ -0,0 +1,4 @@
- name: Nectarine
loc: http://nectarine.ers35.net:8000/necta192.mp3
- name: TheBase
loc: http://radio.thebase.sc:8000/stream

View File

@ -3,3 +3,5 @@
# install vim plugins
vim -E +"call dein#update()" +"qall!" /dev/null &>/dev/null
systemctl --user enable mpv.service