I am seriously new to Python and my first project is quite ambitious :D
I'm trying to create an audio player using a QWebView and the HTML5 Audio API.
I want to use Phonon to actually play the media, but I'd like to be able to use the HTML5 Audio API to make an equalizer, like the one in Winamp.
I can get Phonon to play an audio file no problem, but is there a way to connect the audio output to my JavaScript so that I can play around with the different channels etc.?
Is it even the best way? I mean, would doing it this way limit the formats available to my player to those supported by WebKit, or would I still be able to play any format Phonon is able to play? (I'm assuming here, that Phonon would stream a raw/decoded version of the audio to my JavaScript, which I could then use via the Audio API)
If this isn't possible I could make a simple JavaScript wrapper around a Phonon AudioOutput object I suppose?
Any thoughts?
I haven't worked with the Qt framework, but peeking at the QWebView docs seems like there's no readily available solution to communicate with the window object.
If you want to work with a familiar protocol, then I suggest you look at the Flask microframework. It's basically a small piece of opinionated code where all the application behavior is provided by functions that receive and then return HTTP request and response objects. Here's the official streaming documentation so you can get an idea how building a response object looks like.
It seems you figured out how to generate the output, this would mean you'd only need to run the built-in Flask server at runtime and transport the audio data to your JavaScript client over HTTP.
Related
I want to create a web application(Flask- A Flashcard AI), a part of which is a bot which needs to directly interact with the human through speech recognition and text-to-speech. I have pyttsx3 and speech_recognition installed for that, where I am confused is how am I supposed to get the user's audio as input and then send it to the backend. I have tried to look up YouTube tutorials and asked other people about the same, the only success I've had is learning about Navigator.MediaDevices.getUserMedia. I want to make the communication fluent, and I will have to send the data to the back-end as well. I am not sure how to send it to the back-end and get the user media fluently, I could use Navigator.MediaDevices.getUserMedia and convert it into an audio file(not sure how to do that yet but I think I'll figure it out eventually, and having the user upload a audio recording won't be nice at all), but then that'll take up a lot of space on the database.
If you just want to process some action based on voice you can use speech API.
https://developer.mozilla.org/en-US/docs/Web/API/Web_Speech_API
This API will be able to give you text based captions which you can easily store in the database.
If you need to store audio on server side you would convert that to some loassy format like mp3 or aac to save space.
I am fiddling around w/ snowboy and PyAudio. I want to automatically listen to a web radio, listen for a hotword via snowboy, record the succeeding X seconds, pass them via SpeechRecognition to the Google Speech-to-Text API and send an email with the contents to myself. I wrote a working proof of concept, which listens to my microphone and does everthing mentioned above. Unfortunately, I am not able to get PyAudio to work with an online audio stream provided by a simple .pls file. Does anyone know if this is an intended use case of PyAudio?
Is this even possible to accomplish?
If not, does anyone know of an alternative to listen to an audio stream and provide it either via PyAudio or another library to snowboy?
Thanks in advance. ;)
You do not need pyaudio, it is a module to record from the microphone, instead you have to implement your own class to read from a stream like snowboydecoder_arecord. To create stream from pls try ffmpeg-python.
I would like to implement a server in Python that streams music in MP3 format over HTTP. I would like it to broadcast the music such that a client can connect to the stream and start listening to whatever is currently playing, much like a radio station.
Previously, I've implemented my own HTTP server in Python using SocketServer.TCPServer (yes I know BaseHTTPServer exists, just wanted to write a mini HTTP stack myself), so how would a music streamer be different architecturally? What libraries would I need to look at on the network side and on the MP3 side?
The mp3 format was designed for streaming, which makes some things simpler than you might have expected. The data is essentially a stream of audio frames with built-in boundary markers, rather than a file header followed by raw data. This means that once a client is expecting to receive audio data, you can just start sending it bytes from any point in an existing mp3 source, whether it be live or a file, and the client will sync up to the next frame it finds and start playing audio. Yay!
Of course, you'll have to give clients a way to set up the connection. The de-facto standard is the SHOUTcast (ICY) protocol. This is very much like HTTP, but with status and header fields just different enough that it isn't directly compatible with Python's built-in http server libraries. You might be able to get those libraries to do some of the work for you, but their documented interfaces won't be enough to get it done; you'll have to read their code to understand how to make them speak SHOUTcast.
Here are a few links to get you started:
https://web.archive.org/web/20220912105447/http://forums.winamp.com/showthread.php?threadid=70403
https://web.archive.org/web/20170714033851/https://www.radiotoolbox.com/community/forums/viewtopic.php?t=74
https://web.archive.org/web/20190214132820/http://www.smackfu.com/stuff/programming/shoutcast.html
http://en.wikipedia.org/wiki/Shoutcast
I suggest starting with a single mp3 file as your data source, getting the client-server connection setup and playback working, and then moving on to issues like live sources, multiple encoding bit rates, inband meta-data, and playlists.
Playlists are generally either .pls or .m3u files, and essentially just static text files pointing at the URL for your live stream. They're not difficult and not even strictly necessary, since many (most?) mp3 streaming clients will accept a live stream URL with no playlist at all.
As for architecture, the field is pretty much wide open. You have as many options as there are for HTTP servers. Threaded? Worker processes? Event driven? It's up to you. To me, the more interesting question is how to share the data from a single input stream (the broadcaster) with the network handlers serving multiple output streams (the players). In order to avoid IPC and synchronization complications, I would probably start with a single-threaded event-driven design. In python 2, a library like gevent will give you very good I/O performance while allowing you to structure your code in a very understandable way. In python 3, I would prefer asyncio coroutines.
Since you already have good python experience (given you've already written an HTTP server) I can only provide a few pointers on how to extend the ground-work you've already done:
Prepare your server for dealing with Request Headers like: Accept-Encoding, Range, TE (Transfer Encoding), etc. An MP3-over-HTTP player (i.e. VLC) is nothing but an mp3 player that knows how to "speak" HTTP and "seek" to different positions in the file.
Use wireshark or tcpdump to sniff actual HTTP requests done by VLC when playing an mp3 over HTTP, so you know how what request headers you'll be receiving and implement them.
Good luck with your project!
You'll want to look into serving m3u or pls files. That should give you a file format that players understand well enough to hit your http server looking for mp3 files.
A minimal m3u file would just be a simple text file with one song url per line. Assuming you've got the following URLs available on your server:
/playlists/<playlist_name/playlist_id>
/songs/<song_name/song_id>
You'd serve a playlist from the url:
/playlists/myfirstplaylist
And the contents of the resource would be just:
/songs/1
/songs/mysong.mp3
A player (like Winamp) will be able to open the URL to the m3u file on your HTTP server and will then start streaming the first song on the playlist. All you'll have to do to support this is serve the mp3 file just like you'd serve any other static content.
Depending on how many clients you want to support you may want to look into asynchronous IO using a library like Twisted to support tons of simultaneous streams.
Study these before getting too far:
http://wiki.python.org/moin/PythonInMusic
Specifically
http://edna.sourceforge.net/
You'll want to have a .m3u or .pls file that points at a static URI (e.g. http://example.com/now_playing.mp3) then give them mp3 data starting wherever you are in the song when they ask for that file. Probably there are a bunch of minor issues I'm glossing over here...However, at least as forest points out, you can just start streaming the mp3 data from any byte.
Disclaimer: I'm not very familiar with any of the things mentioned in the question title.
Would it be possible to use a browser control (like Webkit) as a frontend for a WSGI app (using a framework like Flask) without starting a local WSGI server?
Basically the requests and responses are managed by a middle layer between the HTML UI and the WSGI backend. A certain URI could mean "Local", for instance "local://" or something similar, and will be routed to the embedded WSGI app with all the original headers etc.
You will lose any features that a normal WSGI server provides unless you implement it yourself or somehow embed a server that is also usable via an API instead of real HTTP requests.
Now that I think of it, this is the only real requirement: A WSGI server that is callable via an API and not just real HTTP requests.
I know the usefulness of this is questionable (and maybe doesn't even make sense). My question is whether this is at all possible?
EDIT: Here's another way of putting it:
I want a single codebase to be both a web app and a desktop app, using an HTML frontend and a Python backend. I don't want to run a server on any port for the desktop app. What's the easiest way to achieve this?
It is in theory possible to write your own WSGI container that implements a full API and adapts that to WSGI. flup might bring some inspiration.
Earlier today I saw exactly what you're asking for -- a way to call WSGI through an API without actually connecting over the network. However, it shouldn't be that hard.
On a side note, you might want to look at PySide, of particular interest to you may be the ability to bind python elements to DOM events, so if you're just looking to trigger python code that's an even shorter route.
If you give some more detail on what you're hoping to achieve we might be able to dial it in for you.
Reviving this, since we're facing the same problem and are about to scale things up from a single view/widget to the whole app.
What I did was to simply set the base URL to something where I serve static content, and from a QRC file that's easy:
html = jinjatemplate.render(...)
self._mainFrame.setHtml(html.decode('utf-8'), Qt.QUrl('qrc:///Orsync/html/'))
For the communication, our HTML uses AJAX over jQuery for most things. You could wrap that in a layer that either does $.post(...) or api.post(...) like this:
self._mainFrame.addToJavaScriptWindowObject('api', self._webapi)
You'd need to decode the URL and create a request object yourself, but maybe that's not too hard to do? We use very few URLs currently (who are mapped directly to python objects/functions) so it's easy to do the mapping ourselves.
Data that goes back is just sent using QMainFrame.evaluateJavaScript(...), either as a direct Qt call or as a bunch of code lines fetched using $.getScript(...) (which just evaluates the code received).
I'm currently rebuilding things a bit using CherryPy, and it maps urls -> Python objects straight off, so I'm hoping there's something to be gained by that.
Otherwise, I would wish one could run QWebKit over named pipes or something similarly localized and not a tcp-socket. :)
I am looking for a pure Javascript/Python upload example, that uses server polling instead of client-side SWF to display upload progress (like the one on rapidshare.com for example)
Currently, website is running on the standalone wsgi server included with Werkzeug framework, but may be moved to mod_wsgi if the load increases.
I've tried the gp.fileupload middleware, but can't get it to work. Examples on their website wont work either :|
Website already uses Glow library for other misc client-side stuff, but there is no specific upload-related functionality in it.
If you don't have support on the web side to track the size of the temporary file (or in-memory buffer) of the uploading data as it arrives, I don't know how you'll do this. Some of the popular web servers have special support for this, mostly experimental, but it's not widely supported and what you're trying to do is pretty awkward in general. I've researched this recently and it's pretty poorly supported all around.