Do yall need help adapting this project to be a media player? #6
Replies: 8 comments 21 replies
-
|
@nednoodlehead - I must have missed your response to my comment on SO. Sorry 'bout that. Anyway, back to my comment, this project itself won't turn into a GUI app, but I'm planning on using it for a future GUI project. So, if calling ffmpeg subprocess causes a glitch, I'd like to have a way to avoid it.
I'll take a look at your project later this weekend, to see if maybe the |
Beta Was this translation helpful? Give feedback.
-
|
Well, you got me curious enough to test what I designed Here is a quick demo on how you can load data while playing (need Because I don't use a custom class, I think it's fairly easy to program with import ffmpegio
import simpleaudio as sa
from pprint import pprint
file = "path_to_audio_or_video_file.mp4"
# grab the file info
info = ffmpegio.probe.full_details(file)
sinfo = next((s for s in info["streams"] if s["codec_type"] == "audio"))
pprint(sinfo)
sample_rate = int(sinfo["sample_rate"])
num_channels = 2 # int(sinfo["channels"]) # force stereo
sample_fmt = "s16" # force signed 16-bit (simpleaudio only supports integer-multiple byte formats)
bytes_per_sample = 2 # s16 = 2 bytes/sample
# estimate the number of samples (try stream duration first, if not available use container duration)
nb_samples = int(
float(sinfo.get("duration", info["format"].get("duration")) * sample_rate)
)
# preallocate the buffer
ntotal = nb_samples * num_channels # total data size in number of bytes
audio_data = bytearray(ntotal) # playback buffer
# open ffmpegio's stream-reader to read nblk samples at a time
nblk = sample_rate # 1 second (you can use any number you wish)
with ffmpegio.open(
file, "ra", sample_fmt=sample_fmt, ac=num_channels, blocksize=nblk
) as f:
# read the first block of data and place them on the playback buffer
data = f.read(nblk)["buffer"]
nwritten = len(data)
audio_data[:nwritten] = data
# start the audio player (before finish loading the data)
play_obj = sa.play_buffer(audio_data, num_channels, bytes_per_sample, sample_rate)
# queue up rest of the data while playing
for block in f: # process one block at a time
# make sure not to overflow the playback buffer
data = block["buffer"]
n = len(data)
nend = min(nwritten + n, ntotal)
audio_data[nwritten:nend] = data[: nend - nwritten]
nwritten = nend # update bytes written |
Beta Was this translation helpful? Give feedback.
-
I'm curious to see |
Beta Was this translation helpful? Give feedback.
-
|
Here is a question on |
Beta Was this translation helpful? Give feedback.
-
|
Here is # playback configuration (shared by both ffmpegio and pyaudio)
ar = 44100 # playback sampling rate
ac = 2 # number of channels
width = 2 # signed 2-byte integer format
sample_fmt = "s16"
# open ffmpegio's stream-reader
with ffmpegio.open(file, "ra", sample_fmt=sample_fmt, ac=ac, ar=ar) as f:
# define pyaudio callback
def callback(_, nblk, *__):
# read nblk samples from the ffmpeg and pass it onto pyaudio
data = f.read(nblk)["buffer"]
return (data, pyaudio.paContinue)
# start pyaudio stream
p = pyaudio.PyAudio()
format = p.get_format_from_width(width, unsigned)
stream = p.open(rate, channels, format, output=True, stream_callback=callback,)
stream.start_stream()
# wait for stream to finish
while stream.is_active():
sleep(0.1)
stream.stop_stream()
stream.close()
p.terminate()You can find a working example in the |
Beta Was this translation helpful? Give feedback.
-
|
Also got the cross-fading to work with Here are some keys:
If you have any questions, ask here (paste the code lines in question) |
Beta Was this translation helpful? Give feedback.
-
|
Do you want this media player bit I'm gunna create to be apart of this repo or should we have a separate one? I'm fine with it in here, but it you want to separate it, no biggie. |
Beta Was this translation helpful? Give feedback.
-
|
Hey, just seeing where this project is at, have you made any type of media-type player like we were talking about? My current goal is to learn a bit of PyQt5 (in progress :) ), then revamp my Punge project with PyQt5 and this project. Of course it'll take me a few weeks to get a working ffmpegio up and going how i want it, but, hopefully soon ! |
Beta Was this translation helpful? Give feedback.



Uh oh!
There was an error while loading. Please reload this page.
-
I'm not too well versed with like audio-specific manipulation, but if you get me a function that I can play audio I can make an audio player out of it.
This is mostly a response to Kesh on StackOverflow
I made one before using PyDub bindings (Which uses SimpleAudio, which uses FFMPEG). It is a very convoluted process, and making a binding through here would be significantly easier.
The current project that I'm using my audioplayer in is Punge.
A large part of the gimmick that makes the audio player work is that the music does not have an inherent 'time.sleep()' type of attribute, so if you call "pydub.playback._play_with_simpleaudio(audiosegment)", it won't do anything. But if you call a time.sleep() along with it, it will play for the duration of the time.sleep()
There are also two limitations that I've encountered; I'm unsure of this is a hole in the package I'm using, or I haven't figured out a way around (I'll admit it, I haven't tried too much): Scrubbing and count of length of song & time left.
The current player I have is fairly bugless but has two main issues that may be solved by using a new library (like this one):
1). It is slightly clunky and for long videos (15m>), it can take a few second to initialize.
2). Memory usage for the app directly correlates with the length of the current video. 50mb average, and up to 150mb for longer videos
Let me know what you guys think, and again, I would probably need binds for playing audio, as I don't know much about how audio specifically works.
Beta Was this translation helpful? Give feedback.
All reactions