i'm new to Gstreamer and basically have been reading the documentation for a day now. I need a program that captures audio from an audio input for 10-15 sec every 5 mins and stores it into a file.
The only thing i have no idea how to do is the capture itself, since i haven't worked with inputs before. Now i found this code on the net but have no idea if it will help me (i understand most of it but have no idea where does it save the files, if it saves them at all) any help would be really appreciated
import gi
gi.require_version('Gst', '1.0')
from gi.repository import GObject, Gst, Gtk
GObject.threads_init()
Gst.init(None)
pipeline = Gst.Pipeline()
autoaudiosrc = Gst.ElementFactory.make("autoaudiosrc", "autoaudiosrc")
audioconvert = Gst.ElementFactory.make("audioconvert", "audioconvert")
vorbisenc = Gst.ElementFactory.make("vorbisenc", "vorbisenc")
oggmux = Gst.ElementFactory.make("oggmux", "oggmux")
filesink = Gst.ElementFactory.make("filesink", "filesink")
url = "1.ogg"
filesink.set_property("location",url)
pipeline.add( autoaudiosrc)
pipeline.add( audioconvert)
pipeline.add( vorbisenc)
pipeline.add( oggmux)
pipeline.add( filesink)
autoaudiosrc.link( audioconvert)
audioconvert.link( vorbisenc)
vorbisenc.link( oggmux)
oggmux.link( filesink)
pipeline.set_state(Gst.State.PLAYING)
Gtk.main()
P.S. a professor suggested gstreamer to me, and i haven't found a good alternative, so that's why i'm trying it, but if there is a better way out there please tell me, since i feel like gstreamer is more in a player/ playback nature
the question is nicely written, however you could try out more investigation before you ask.. also you can add tag python and the code would be highlighted..
Anyway gstreamer is perfectly ok for saving to file..
The example saves the output into file called 1.ogg in current directory where you run the script.
Have you already run the script? look for that file where you ran it..
The filesink element does the actual file saving. If you want to save each capture in another file you could generate some filename in format for example YYYY-MM-DD_HH_mm_ss.ogg(this is typical datetime format where YYYY represents year, MM month etc).
You can either
run the script every 5 minues if you are on linux thic could be a cron job
or just a bash script..
or you can code it in python in same script to run the gstreamer pipe again and again.. this would be harder but 'nicer'
import gi
import datetime, time
import sys
import signal
signal.alarm(15)
gi.require_version('Gst', '1.0')
from gi.repository import GObject, Gst, Gtk
GObject.threads_init()
Gst.init(None)
pipeline = Gst.Pipeline()
autoaudiosrc = Gst.ElementFactory.make("autoaudiosrc", "autoaudiosrc")
audioconvert = Gst.ElementFactory.make("audioconvert", "audioconv")
audioresample= Gst.ElementFactory.make("audioresample","audioresample")
vorbisenc = Gst.ElementFactory.make("vorbisenc", "vorbisenc")
oggmux = Gst.ElementFactory.make("oggmux", "oggmux")
filesink = Gst.ElementFactory.make("filesink", "filesink")
url = datetime.datetime.now()
audioresample.set_property("quality", 10)
vorbisenc.set_property("quality", 1)
filesink.set_property("location",url)
pipeline.add( autoaudiosrc)
pipeline.add( audioconvert)
pipeline.add( vorbisenc)
pipeline.add( oggmux)
pipeline.add( filesink)
pipeline.add( audioresample)
autoaudiosrc.link( audioconvert)
audioconvert.link( audioresample)
audioresample.link(vorbisenc)
vorbisenc.link( oggmux)
oggmux.link( filesink)
pipeline.set_state(Gst.State.PLAYING)
Gtk.main()
As promised, the full code. The best audio quality you can have, plus it saves the files as a date and dime now.
As for the storing, i made a bash script that works perfectly, so that solved that (found out that if i do it in the script itself, the file never saves properly)
Related
I am working on a project that requires sound snippets to be played from MP3 files in a playlist. The files are full songs.
I have tried pygame mixer and I can pass the start time of the file, but I cannot pass the end time that I want the music to stop, or be able to fade-in and fade out the current snippet.
I have looked at the vlc and ffmpeg libraries, but I do not see the functionality I am looking for.
I'm hoping someone may be aware of a library out there that may be able to do what I am trying to accomplish.
I finally figured out how to do exactly what I wanted to do!
In the spirit of helping others I am posting an answer to my own question.
My development environment:
Mac OS Mojave 10.14.6
Python 3.7.4
PyAudio 0.2.11
PyDub 0.23.1
Here it is in it's most rudimentary form:
import pyaudio
from pydub import AudioSegment
# Assign a mp3 source file to the PyDub Audiosegment
mp3 = AudioSegment.from_mp3("path_to_your_mp3_file")
# Specify starting and ending offsets from the beginning of the stream
# then apply a fadein and fadeout. All values are in millisecond (seconds * 1000).
mp3 = mp3[int(43000):int(58000)].fade_in(2000).fade_out(2000)
# In the above example the music will start 43 seconds into the track with a 2 second
# fade-in, and only play for 15 seconds with a 2 second fade-out. If you don't need
# these features, just comment out the line and the full mp3 will play.
# Assign the PyAudio player
player = pyaudio.PyAudio()
# Create the stream from the chosen mp3 file
stream = player.open(format = player.get_format_from_width(mp3.sample_width),
channels = mp3.channels,
rate = mp3.frame_rate,
output = True)
data = mp3.raw_data
while data:
stream.write(data)
data=0
stream.close()
player.terminate()
It isn't in the example above, but there is a way to process the stream and increase/decrease/mute the volume of the music.
One other thing that could be done is to set up a thread to pause the processing (writing) of the stream, which would emulate a pause button in a player.
I have a QMediaPlayer object, which if I try to get the duration of before letting the file buffer enough, will return -1. To my understanding, this is because the file is loaded asynchronously and duration (and subsequently position) cannot be known since it is unknown if the file is fully loaded yet.
My initial idea to solve this was to run media.play(), immediately followed by media.stop(). This does absolutely nothing. Then, I considered running media.play() and media.pause(). This does not work either. I imagine this is because the media needs to buffer for a significant period of time before the duration can be obtained. Also, this "solution" would not have been ideal regardless.
How can I get the duration of a QMediaPlayer object before the file has been played?
One possible solution is to use the durationChanged signal:
from PyQt5 import QtCore, QtMultimedia
if __name__ == '__main__':
import sys
app = QtCore.QCoreApplication(sys.argv)
player = QtMultimedia.QMediaPlayer()
#QtCore.pyqtSlot('qint64')
def on_durationChanged(duration):
print(duration)
player.stop()
QtCore.QCoreApplication.quit()
player.durationChanged.connect(on_durationChanged)
file = "/path/of/small.mp4"
player.setMedia(QtMultimedia.QMediaContent(QtCore.QUrl.fromLocalFile(file)))
player.play()
sys.exit(app.exec())
from gtts import *
import os
import vlc
def sauvegarde(text,i):
tts = gTTS(text, lang='fr')
tts.save("text"+str(i)+".mp3")
def play(file):
p = vlc.MediaPlayer(file)
p.play()
text = "Salut Santo c\'est Alexis, ton maitre qui te parle"
text2="Bonjour Santo"
sauvegarde(text,1)
sauvegarde(text2,2)
play("text1.mp3")
play("text2.mp3")
os.system("pause")
When I run this code the two .mp3 files that I created previously are being played at the same time. Any ideas how to play the second one after the first is finished?
vlc doesn't seem to have a blocking version of play as far as I can tell, so probably the easiest way to accomplish this is to manually wait for the first mp3 to finish. So to make a blocking version of your play function, try something like this:
import time
def play(file):
p = vlc.MediaPlayer(file)
p.play()
while(p.is_playing()):
time.sleep(0.1)
This will check is p is still playing every 100ms. Only when it is done playing, the play function will return.
Alternatively, you can use vlc.MediaListPlayer and vlc.MediaList to create a playlist containing your mp3's.
I want to play a .wav file in Python 3.4. Additonally, I want python to play the file rather than python open the file to play in VLC, media player etc..
As a follow up question, is there any way for me to combine the .wav file and the .py file into a standalone exe.
Ignore the second part of the question if it is stupid, I don't really know anything about compiling python.
Also, I know there have been other questions about .wav files, but I have not found one that works in python 3.4 in the way I described.
Using pyaudio you may get incorrect playback due to speed, consider instead:
sudo apt-get install python-pygame
Windows:
choco install python-pygame?
def playSound(filename):
pygame.mixer.music.load(filename)
pygame.mixer.music.play()
import pygame
pygame.init()
playSound('hellyeah.wav')
I fixed the problem by using the module pyaudio, and the module wave to read the file.
I will type example code to play a simple wave file.
import wave, sys, pyaudio
wf = wave.open('Sound1.wav')
p = pyaudio.PyAudio()
chunk = 1024
stream = p.open(format =
p.get_format_from_width(wf.getsampwidth()),
channels = wf.getnchannels(),
rate = wf.getframerate(),
output = True)
data = wf.readframes(chunk)
while data != '':
stream.write(data)
data = wf.readframes(chunk)
If you happen to be using linux a simple solution is to call aplay.
import os
wav_file = "./Hello.wav"
os.system(f'aplay {wav_file}')
I would like to be able to play a sound file in a ipython notebook.
My aim is to be able to listen to the results of different treatments applied to a sound directly from within the notebook.
Is this possible? If yes, what is the best solution to do so?
The previous answer is pretty old. You can use IPython.display.Audio now. Like this:
import IPython
IPython.display.Audio("my_audio_file.mp3")
Note that you can also process any type of audio content, and pass it to this function as a numpy array.
If you want to display multiple audio files, use the following:
IPython.display.display(IPython.display.Audio("my_audio_file.mp3"))
IPython.display.display(IPython.display.Audio("my_audio_file.mp3"))
A small example that might be relevant : http://nbviewer.ipython.org/5507501/the%20sound%20of%20hydrogen.ipynb
it should be possible to avoid gooing through external files by base64 encoding as for PNG/jpg...
The code:
import IPython
IPython.display.Audio("my_audio_file.mp3")
may give an error of "Invalid Source" in IE11, try in other browsers it should work fine.
The other available answers added an HTML element which I disliked, so I created the ringbell, which gets you both play a custom sound as such:
from ringbell import RingBell
RingBell(
sample = "path/to/sample.wav",
minimum_execution_time = 0,
verbose = True
)
and it also gets you a one-lines to play a bell when a cell execution takes more than 1 minute (or a custom amount of time for that matter) or is fails with an exception:
import ringbell.auto
You can install this package from PyPI:
pip install ringbell
If the sound you are looking for could be also a "Text-to-Speech", I would like to mention that every time a start some long process in the background, I queue the execution of a cell like this too:
from IPython.display import clear_output, display, HTML, Javascript
display(Javascript("""
var msg = new SpeechSynthesisUtterance();
msg.text = "Process completed!";
window.speechSynthesis.speak(msg);
"""))
You can change the text you want to hear with msg.text.