Skip to content

Commit 7e53714

Browse files
committed
- version 0.9.2.11
- finalizing mplayer recording - starting vlc recording (disabled at the moment) - a python 2 fix
1 parent 0c18246 commit 7e53714

File tree

10 files changed

+122
-62
lines changed

10 files changed

+122
-62
lines changed

Changelog

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
2023-06-20 s-n-g
2+
* version 0.9.2.11
3+
* implementing station recording for MPlayer media player
4+
* players' config file will be backed up on Windows
5+
* fixing a couple of potential crashes
6+
17
2023-06-14 s-n-g
28
* version 0.9.2.10
39
* all PyRadio threads will terminate when Alt-F4 or the
@@ -14,7 +20,7 @@
1420
2023-06-13 s-n-g
1521
* version 0.9.2.8
1622
* \o will open the config directory in a file manager
17-
* implementing station recording vor MPV media player
23+
* implementing station recording for MPV media player
1824
* implementing playback pause for MPV media player, when
1925
player in recording mode
2026
* fixing Windows installayion scripts

README.html

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,12 @@ <h2 id="requirements">Requirements <span style="padding-left: 10px;"><sup style=
207207
<h2 id="changelog">Changelog <span style="padding-left: 10px;"><sup style="font-size: 50%"><a href="#" title="Go to top of the page">Top</a></sup></span></h2>
208208
<pre style="height: 200px;">
209209

210+
2023-06-20 s-n-g
211+
* version 0.9.2.11
212+
* implementing station recording for MPlayer media player
213+
* players' config file will be backed up on Windows
214+
* fixing a couple of potential crashes
215+
210216
2023-06-14 s-n-g
211217
* version 0.9.2.10
212218
* all PyRadio threads will terminate when Alt-F4 or the
@@ -223,7 +229,7 @@ <h2 id="changelog">Changelog <span style="padding-left: 10px;"><sup style="font-
223229
2023-06-13 s-n-g
224230
* version 0.9.2.8
225231
* \o will open the config directory in a file manager
226-
* implementing station recording vor MPV media player
232+
* implementing station recording for MPV media player
227233
* implementing playback pause for MPV media player, when
228234
player in recording mode
229235
* fixing Windows installayion scripts

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "pyradio"
3-
version = "0.9.2.10"
3+
version = "0.9.2.11"
44
authors = [
55
{ name="Ben Dowling", email="[email protected]" },
66
{ name="Spiros Georgaras", email="[email protected]" },

pyradio/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
" pyradio -- Console radio player. "
22

3-
version_info = (0, 9, 2, 10)
3+
version_info = (0, 9, 2, 11)
44

55
# Set it to True if new stations have been
66
# added to the package's stations.csv

pyradio/config.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,10 @@
1313
from shutil import copyfile, move, Error as shutil_Error
1414
import threading
1515
from copy import deepcopy
16-
from subprocess import Popen, DEVNULL
16+
try:
17+
from subprocess import Popen, DEVNULL
18+
except ImportError:
19+
from subprocess import Popen
1720
from platform import system
1821
if system().lower() == 'windows':
1922
from os import startfile

pyradio/install.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
''' This is PyRadio version this
1616
install.py was released for
1717
'''
18-
PyRadioInstallPyReleaseVersion = '0.9.2.10'
18+
PyRadioInstallPyReleaseVersion = '0.9.2.11'
1919

2020
import locale
2121
locale.setlocale(locale.LC_ALL, "")

pyradio/player.py

Lines changed: 52 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,7 @@ def recording(self, val):
316316
self._recording = 0
317317
logger.error('\n\nsetting recording to {}'.format(self._recording))
318318

319-
def getrecording_filename(self, name, extension):
319+
def get_recording_filename(self, name, extension):
320320
f = datetime.now().strftime('%Y-%m-%d %H-%M-%S') + " " + name + extension
321321
return os.path.join(self._cnf.recording_dir, f)
322322

@@ -397,6 +397,35 @@ def set_volume(self, vol):
397397
while old_vol == int(self.volume):
398398
sleep(.1)
399399

400+
def create_monitor_player(self, stop):
401+
logger.info('\n\n======|||==========')
402+
# self.monitor_opts.append('--volume')
403+
# self.monitor_opts.append('300')
404+
logger.info(self.monitor_opts)
405+
while not os.path.exists(self.recording_filename):
406+
sleep(.1)
407+
if stop():
408+
logger.error('Asked to stop. Exiting....')
409+
return
410+
while os.path.getsize(self.recording_filename) < 12000:
411+
sleep(.1)
412+
if stop():
413+
logger.error('Asked to stop. Exiting....')
414+
return
415+
if stop():
416+
logger.error('Asked to stop. Exiting....')
417+
return
418+
if logger.isEnabledFor(logging.INFO):
419+
logger.info('\n\n')
420+
logger.info('----==== {} monitor started ====----'.format(self.PLAYER_NAME))
421+
logger.info('\n\n')
422+
self.monitor_process = subprocess.Popen(
423+
self.monitor_opts, shell=False,
424+
stdout=subprocess.PIPE,
425+
stdin=subprocess.PIPE,
426+
stderr=subprocess.STDOUT
427+
)
428+
400429
def save_volume(self):
401430
pass
402431

@@ -1570,11 +1599,17 @@ def play(self,
15701599
logger.info('----==== {} player started ====----'.format(self.PLAYER_NAME))
15711600
if self.recording == self.RECORD_AND_LISTEN \
15721601
and self.PLAYER_NAME != 'mpv':
1573-
threading.Thread(
1574-
target=self.create_monitor_player,
1575-
args=(lambda: self.stop_mpv_status_update_thread or \
1576-
self.stop_win_vlc_status_update_thread, )
1577-
).start()
1602+
if self.PLAYER_NAME == 'mplayer':
1603+
threading.Thread(
1604+
target=self.create_monitor_player,
1605+
args=(lambda: self.stop_mpv_status_update_thread or \
1606+
self.stop_win_vlc_status_update_thread, )
1607+
).start()
1608+
else:
1609+
threading.Thread(
1610+
target=self.create_monitor_player,
1611+
args=(lambda: self.stop_mpv_status_update_thread, )
1612+
).start()
15781613

15791614
def _sendCommand(self, command):
15801615
''' send keystroke command to player '''
@@ -1972,7 +2007,7 @@ def _buildStartOpts(self, streamUrl, playList=False):
19722007

19732008
logger.error('\n\nself._recording = {}'.format(self._recording))
19742009
if self._recording > 0:
1975-
self.recording_filename = self.getrecording_filename(self.name, '.mkv')
2010+
self.recording_filename = self.get_recording_filename(self.name, '.mkv')
19762011
opts.append('--stream-record=' + self.recording_filename)
19772012
if logger.isEnabledFor(logging.DEBUG):
19782013
logger.debug('---=== Starting Recording: "{}" ===---',format(self.recording_filename))
@@ -2357,29 +2392,6 @@ def __init__(self,
23572392
)
23582393
self.config_files = self.all_config_files['mplayer']
23592394

2360-
def create_monitor_player(self, stop):
2361-
while not os.path.exists(self.recording_filename):
2362-
sleep(.1)
2363-
if stop():
2364-
logger.error('Asked to stop. Exiting....')
2365-
return
2366-
while os.path.getsize(self.recording_filename) < 500:
2367-
sleep(.1)
2368-
if stop():
2369-
logger.error('Asked to stop. Exiting....')
2370-
return
2371-
if stop():
2372-
logger.error('Asked to stop. Exiting....')
2373-
return
2374-
if logger.isEnabledFor(logging.INFO):
2375-
logger.info('----==== {} monitor started ====----'.format(self.PLAYER_NAME))
2376-
self.monitor_process = subprocess.Popen(
2377-
self.monitor_opts, shell=False,
2378-
stdout=subprocess.PIPE,
2379-
stdin=subprocess.PIPE,
2380-
stderr=subprocess.STDOUT
2381-
)
2382-
23832395
def save_volume(self):
23842396
if platform.startswith('win'):
23852397
return self._do_save_volume('volume={}\r\n')
@@ -2485,7 +2497,7 @@ def _buildStartOpts(self, streamUrl, playList=False):
24852497
''' not -playlist, find and remove url '''
24862498
i = [y for y, x in enumerate(monitor_opts) if x == streamUrl][0]
24872499
del monitor_opts[i]
2488-
self.recording_filename = self.getrecording_filename(self.name, '.mkv')
2500+
self.recording_filename = self.get_recording_filename(self.name, '.mkv')
24892501
monitor_opts.append(self.recording_filename)
24902502
opts.append('-dumpstream')
24912503
opts.append('-dumpfile')
@@ -2725,7 +2737,10 @@ def _buildStartOpts(self, streamUrl, playList=False):
27252737
logger.info('vlc log file: "{}"'.format(self._vlc_stdout_log_file))
27262738

27272739
else:
2728-
opts = [self.PLAYER_CMD, '-Irc', '-vv', self._url_to_use(streamUrl)]
2740+
if self.recording == self.NO_RECORDING:
2741+
opts = [self.PLAYER_CMD, '-Irc', '-vv', self._url_to_use(streamUrl)]
2742+
else:
2743+
opts = [self.PLAYER_CMD, '--no-one-instance', '-Irc', '-vv', self._url_to_use(streamUrl)]
27292744

27302745

27312746
''' take care of command line parameters '''
@@ -2742,10 +2757,14 @@ def _buildStartOpts(self, streamUrl, playList=False):
27422757
## opts.append(r'file/ts:C:\Users\Spiros\AppData\Roaming\pyradio\recordings\rec.mkv')
27432758
logger.error('\n\nself._recording = {}'.format(self._recording))
27442759
if self._recording > 0:
2745-
self.recording_filename = self.getrecording_filename(self.name, '.mkv')
2760+
monitor_opts = opts[:]
2761+
i = [y for y, x in enumerate(monitor_opts) if x == streamUrl][0]
2762+
del monitor_opts[i]
2763+
self.recording_filename = self.get_recording_filename(self.name, '.mkv')
27462764
opts.append('--sout')
27472765
opts.append(r'file/ts:' + self.recording_filename)
27482766
opts.append(self.recording_filename)
2767+
monitor_opts.append(self.recording_filename)
27492768
if logger.isEnabledFor(logging.DEBUG):
27502769
logger.debug('---=== Starting Recording: "{}" ===---',format(self.recording_filename))
27512770
return opts, monitor_opts

pyradio/radio.py

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8620,17 +8620,19 @@ def keypress(self, char):
86208620
if self.ws.operation_mode == self.ws.NORMAL_MODE:
86218621
if char == ord('|'):
86228622
self._reset_status_bar_right()
8623-
# if self.player.PLAYER_NAME == 'mpv':
8624-
self.player.recording = 1 if self.player.recording == 0 else 0
8625-
if self.player.recording > 0:
8626-
if self.player.isPlaying():
8627-
self.player.already_playing = True
8623+
if self.player.PLAYER_NAME != 'vlc':
8624+
self.player.recording = 1 if self.player.recording == 0 else 0
8625+
if self.player.recording > 0:
8626+
if self.player.isPlaying():
8627+
self.player.already_playing = True
8628+
else:
8629+
self.player.already_playing = False
86288630
else:
86298631
self.player.already_playing = False
8632+
self._show_recording_status_in_header()
8633+
self._show_recording_toggle_window()
86308634
else:
8631-
self.player.already_playing = False
8632-
self._show_recording_status_in_header()
8633-
self._show_recording_toggle_window()
8635+
self._print_not_implemented_yet()
86348636

86358637
elif char == curses.ascii.BEL:
86368638
''' ^G - show groups '''
@@ -8868,6 +8870,9 @@ def keypress(self, char):
88688870
elif char in (curses.KEY_ENTER,
88698871
ord('\n'), ord('\r'),
88708872
curses.KEY_RIGHT, ord('l')):
8873+
if self.player.isPlaying() and \
8874+
self.player.playback_is_on:
8875+
self._stop_player()
88718876
self._start_player()
88728877
self._do_display_notify()
88738878
return

recording.html

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -68,31 +68,41 @@ <h2 id="table-of-contents">Table of Contents <span style="padding-left: 10px;"><
6868
<h2 id="intro">Intro <span style="padding-left: 10px;"><sup style="font-size: 50%"><a href="#" title="Go to top of the page">Top</a></sup></span></h2>
6969
<p><strong>PyRadio v. 0.9.2.8</strong> introduces the ability to record stations, a feature used mainly to facilitate another feature: the ability to <em>pause and resume playback</em>.</p>
7070
<p>All supported media players (<strong>MPV</strong>, <strong>MPlayer</strong> and <strong>VLC</strong>) support stream recording, each implementing it in a different way, which pose a challenge for the front end implementation.</p>
71-
<p>Let us see the differences.</p>
71+
<p>Before we see the differences, let us talk about some things that will make the whole thing easier to understand.</p>
72+
<p>When it comes to recording a stream the program has to provide two things:</p>
73+
<ol type="1">
74+
<li><p>a <strong>recorder</strong>, which is the component that will connect to the stream (in our case the station), receive its data, and write them in a file that media players can recognize and reproduce.<br />
75+
<br />
76+
Since this is the program receiving data from the station, it will also receive song titles, or other stations data, but will not save them to the recorded file.</p></li>
77+
<li><p>a <strong>monitor</strong>, which is the component that will reproduce the saved stream so that the user can monitor what is being downloaded.<br />
78+
<br />
79+
The <strong>monitor</strong> will just reproduce what’s written to the file by the <strong>recorder</strong>, so it knows nothing about a station, it’s data and song titles transmitted by it.</p></li>
80+
</ol>
81+
<p>Now, let’s see how <strong>PyRadio</strong>’s supported players behave.</p>
7282
<h3 id="mpv">MPV</h3>
7383
<p><strong>MPV</strong> stream recording has the following characteristics:</p>
7484
<ul>
75-
<li>it is done using the <strong>–stream-record</strong> command line parameter.</li>
7685
<li>it is considered an <strong>experimental feature</strong> by the <strong>MPV</strong> developers.<br />
7786
Radio streaming uses well known and established codecs (mainly mp3 and aac) and I have had no broken recording while testing the feature (even with flac stations).</li>
78-
<li><strong>MPV</strong> has the ability to play and record a stream at the same time.<br />
87+
<li><strong>MPV</strong> has the ability to play and record a stream at the same time (both the <strong>recorder</strong> and the <strong>monitor</strong> components are active simultaneously).<br />
7988
This is very convenient, since all one has to do is add a command line parameter and start recording, while listening to what’s being recorded.</li>
8089
<li>adjusting the volume or muting the player will not affect what’s being recorded.</li>
8190
<li>when paused, the player will pause the playback but will keep recording the stream. Furthermore, song titles will stop being updated, but will be correctly displayed and updated when playback is resumed.</li>
8291
</ul>
8392
<h3 id="mplayer">MPlayer</h3>
84-
<p><strong>Note</strong>: <strong>MPlayer</strong> recording has not been implemented yet!</p>
8593
<p><strong>MPlayer</strong> stream recording has the following characteristics:</p>
8694
<ul>
87-
<li>it is done using the <strong>-dumpstream</strong> and <strong>-dumpfile</strong> command line parameters.</li>
8895
<li>it does not have the ability to record and play a stream at the same time.<br />
89-
This means that the front end will have to use two <em>mplayer</em> instances: one to record the stream and one more to play the recorded file (as it is being recorded).</li>
96+
This means that the front end (<strong>PyRadio</strong>) will have to use two <em>mplayer</em> instances (run <em>mplayer</em> twice): one as a <strong>recorder</strong> and one as a <strong>monitor</strong>.</li>
97+
<li>the <strong>recorder</strong> will display the song titles in addition to saving the output file.</li>
98+
<li>the <strong>monitor</strong> will be started after the output file gets to a certain size, set to 12000 bytes by trial and error.</li>
99+
<li>pausing and resuming the <strong>monitor</strong> for long will lead to song titles being out of sync, since the <strong>recorder</strong> will keep receiving data (and song titles) even when the playback if off.</li>
100+
<li>adjusting the playback volume is of course possible, but there will be no vissible indication for it.</li>
90101
</ul>
91102
<h3 id="vlc">VLC</h3>
92103
<p><strong>Note</strong>: <strong>VLC</strong> recording has not been implemented yet!</p>
93104
<p><strong>VLC</strong> stream recording has the following characteristics:</p>
94105
<ul>
95-
<li>it is done using the <strong>–sout</strong> command line parameter.</li>
96106
<li>it does not have the ability to record and play a stream at the same time.<br />
97107
This means that the front end will have to use two <em>vlc</em> instances: one to record the stream and one more to play the recorded file (as it is being recorded).</li>
98108
</ul>

recording.md

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -39,37 +39,48 @@ ___
3939

4040
All supported media players (**MPV**, **MPlayer** and **VLC**) support stream recording, each implementing it in a different way, which pose a challenge for the front end implementation.
4141

42-
Let us see the differences.
42+
Before we see the differences, let us talk about some things that will make the whole thing easier to understand.
43+
44+
When it comes to recording a stream the program has to provide two things:
45+
46+
1. a **recorder**, which is the component that will connect to the stream (in our case the station), receive its data, and write them in a file that media players can recognize and reproduce. \
47+
\
48+
Since this is the program receiving data from the station, it will also receive song titles, or other stations data, but will not save them to the recorded file.
49+
50+
2. a **monitor**, which is the component that will reproduce the saved stream so that the user can monitor what is being downloaded. \
51+
\
52+
The **monitor** will just reproduce what's written to the file by the **recorder**, so it knows nothing about a station, it's data and song titles transmitted by it.
53+
54+
Now, let's see how **PyRadio**'s supported players behave.
4355

4456
### MPV
4557

4658
**MPV** stream recording has the following characteristics:
4759

48-
- it is done using the **--stream-record** command line parameter.
4960
- it is considered an **experimental feature** by the **MPV** developers. \
5061
Radio streaming uses well known and established codecs (mainly mp3 and aac) and I have had no broken recording while testing the feature (even with flac stations).
51-
- **MPV** has the ability to play and record a stream at the same time. \
62+
- **MPV** has the ability to play and record a stream at the same time (both the **recorder** and the **monitor** components are active simultaneously). \
5263
This is very convenient, since all one has to do is add a command line parameter and start recording, while listening to what's being recorded.
5364
- adjusting the volume or muting the player will not affect what's being recorded.
5465
- when paused, the player will pause the playback but will keep recording the stream. Furthermore, song titles will stop being updated, but will be correctly displayed and updated when playback is resumed.
5566

5667
### MPlayer
5768

58-
**Note**: **MPlayer** recording has not been implemented yet!
59-
6069
**MPlayer** stream recording has the following characteristics:
6170

62-
- it is done using the **-dumpstream** and **-dumpfile** command line parameters.
6371
- it does not have the ability to record and play a stream at the same time. \
64-
This means that the front end will have to use two *mplayer* instances: one to record the stream and one more to play the recorded file (as it is being recorded).
72+
This means that the front end (**PyRadio**) will have to use two *mplayer* instances (run *mplayer* twice): one as a **recorder** and one as a **monitor**.
73+
- the **recorder** will display the song titles in addition to saving the output file.
74+
- the **monitor** will be started after the output file gets to a certain size, set to 12000 bytes by trial and error.
75+
- pausing and resuming the **monitor** for long will lead to song titles being out of sync, since the **recorder** will keep receiving data (and song titles) even when the playback if off.
76+
- adjusting the playback volume is of course possible, but there will be no vissible indication for it.
6577

6678
### VLC
6779

6880
**Note**: **VLC** recording has not been implemented yet!
6981

7082
**VLC** stream recording has the following characteristics:
7183

72-
- it is done using the **--sout** command line parameter.
7384
- it does not have the ability to record and play a stream at the same time. \
7485
This means that the front end will have to use two *vlc* instances: one to record the stream and one more to play the recorded file (as it is being recorded).
7586

0 commit comments

Comments
 (0)