Welcome!
This is the community forum for my apps Pythonista and Editorial.
For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.
Voice recorder and play sound
-
@cvp said:
@geniu said:
It plays nothing
Sure that your file exists and is not empty? Try it by tapping on it in the Pythonista files browser, then Quick Look, then the play button
Yes, I am. I can play it by Quick Look.
Andprint(os.listdir())
inside the play function shows that the file exists. And I can play it from console by creation a new Player instance -
-
@geniu something like
import sound from sound import Player import ui def play(sender): sender.player.play() v_str = ''' [ { "nodes" : [ { "nodes" : [ ], "frame" : "{{80, 104}, {80, 32}}", "class" : "Button", "attributes" : { "action" : "play", "frame" : "{{80, 104}, {80, 32}}", "title" : "Play", "uuid" : "1D1987D9-DAFA-4228-A0D4-CCDBE54B962B", "class" : "Button", "name" : "play_button", "font_size" : 15, "border_width" : 1 }, "selected" : true } ], "frame" : "{{0, 0}, {240, 240}}", "class" : "View", "attributes" : { "enabled" : true, "background_color" : "RGBA(1.000000,1.000000,1.000000,1.000000)", "tint_color" : "RGBA(0.000000,0.478000,1.000000,1.000000)", "border_color" : "RGBA(0.000000,0.000000,0.000000,1.000000)", "flex" : "" }, "selected" : false } ] ''' v = ui.load_view_str(v_str) v['play_button'].player = Player('4.m4a') v.present('sheet')
-
@cvp said:
@geniu something like
import sound from sound import Player import ui def play(sender): sender.player.play() v_str = ''' [ { "nodes" : [ { "nodes" : [ ], "frame" : "{{80, 104}, {80, 32}}", "class" : "Button", "attributes" : { "action" : "play", "frame" : "{{80, 104}, {80, 32}}", "title" : "Play", "uuid" : "1D1987D9-DAFA-4228-A0D4-CCDBE54B962B", "class" : "Button", "name" : "play_button", "font_size" : 15, "border_width" : 1 }, "selected" : true } ], "frame" : "{{0, 0}, {240, 240}}", "class" : "View", "attributes" : { "enabled" : true, "background_color" : "RGBA(1.000000,1.000000,1.000000,1.000000)", "tint_color" : "RGBA(0.000000,0.478000,1.000000,1.000000)", "border_color" : "RGBA(0.000000,0.000000,0.000000,1.000000)", "flex" : "" }, "selected" : false } ] ''' v = ui.load_view_str(v_str) v['play_button'].player = Player('4.m4a') v.present('sheet')
Thank you. I'll try and let you know if this works.
-
-
@geniu said:
Play still plays after reload app.
I have tested with a .m4a file of only one word, thus...
-
Here is my new code.
import ui from sound import Recorder from sound import Player class recorderView(ui.View): def __init__(self): self.file = '4.m4a' self.player = Player(self.file) self.recorder = Recorder(self.file) record_button = ui.ButtonItem() record_button.title = 'record' record_button.action = self.rec play_button = ui.ButtonItem() play_button.title = 'play' play_button.tint_color = 'red' play_button.action = self.play self.right_button_items = [record_button, play_button] def rec(self, sender): self.recorder.record(3) print(self.recorder.recording) def play(self, sender): print('before calling play method:', self.player.playing) self.player.play() print('after calling play method:', self.player.playing) v = recorderView() v.name = 'Recorder' v.present('sheet')
And here is the piece of play method’s code:
print('before calling play method:', self.player.playing) self.player.play() print('after calling play method:', self.player.playing)
After launch app if I firstly tap the play button sound is playing and output is:
before calling play method: False
after calling play method: TrueBut after recording sound is not playing although
player
exists.
Because I can get player’s attributes.
The output is:before calling play method: False
after calling play method: False -
see
https://gist.github.com/0a8414b4d0edc8a104136f5a88c0acc1
for a simple implementation using a custom View Class.If you want to use a custom view class with the ui designer, you need to specify the custom class name when you create the ui, then you dont need to create the buttons manually, but you would want to assign convience attributes and actions inside view_did_load... but i digress.
This could all be done using sender.superview to get to the root view, and just add custom attributes to the superview -- so no custom class, you would just replace self with sender.superview -- but a class makes everything much cleaner.
Here, i create the player as soon as the recording stops, rather than every play press -- that saves you from having to create a new Player every time. probably, you could create the Recorder once, in the init, but if you want to be able to change file name dynamically, you would create in the record callback as i did.
I got a little fancy, and turn the record/play into the stop button, and disable the other button while playing or recording, which eliminates the need for a third button.
One advantage of a custom class is you can define a custom update method, which in this case can display recorder/player times. you can also define a custom draw() method, which would let you show peak/average bars while recording.
-
@geniu your problem was that you were still creating the Player before the file was created.
think of sound.Player(file) as reading the file as soon as you create the Player... because that is exactly what it does, so it can precache the sound for efficiency.
so, you must create the player only after the recording stops.
if you are using record(3) to record 3 seconds, you'd need to use ui.delay to call another method that arms the player once recorder is done (unfortunately, record doesnt have a finish handler). or create it inside the play callback, just be sure to assign it to self.player so that the object doesnt get deleted while it is playing. -
@JonB, i appreciate your help. Thank you. I need some time to process your answer but now I think everything will be fine.