Audio decoding stopped working ffmpeg - audio

I wrote little program for extracting raw audio date a little while ago. I was busy and in meanwhile I changed OS from Kubuntu 15.04 to 16.04. Libraries are dynamically linked in cmakelists.txt
target_link_libraries(
ffmpeg
#[[ Linking ffmpeg libraries - START ------------------]]
"${CMAKE_SOURCE_DIR}/extern_libs/libffmpeg/lib/libavcodec.so"
"${CMAKE_SOURCE_DIR}/extern_libs/libffmpeg/lib/libavdevice.so"
"${CMAKE_SOURCE_DIR}/extern_libs/libffmpeg/lib/libavutil.so"
"${CMAKE_SOURCE_DIR}/extern_libs/libffmpeg/lib/libavfilter.so"
"${CMAKE_SOURCE_DIR}/extern_libs/libffmpeg/lib/libavformat.so"
"${CMAKE_SOURCE_DIR}/extern_libs/libffmpeg/lib/libswresample.so"
"${CMAKE_SOURCE_DIR}/extern_libs/libffmpeg/lib/libswscale.so"
#[[ Linking ffmpeg libraries - END --------------------]]
)
I started working again on my code but code doesn't work anymore.
if(av_read_frame(m_ctx, &avpkt) >= 0){
got_frame = 0;
avcodec_decode_audio4(c, decoded_frame, &got_frame, &avpkt);
detectSampleFormat((AVSampleFormat)decoded_frame->format);
m_data->allocateMemory(m_duration, decoded_frame->channels);
m_resampler->initResampler(m_fmt, decoded_frame->channel_layout, decoded_frame->sample_rate, decoded_frame->nb_samples);
m_resampler->resampleAudioFrame(decoded_frame, m_data);
}
while(av_read_frame(m_ctx, &avpkt) >= 0){
got_frame = 0;
avcodec_decode_audio4(c, decoded_frame, &got_frame, &avpkt);
m_resampler->resampleAudioFrame(decoded_frame, m_data);
}
Decoded frame should contain information as channel_layout, number of channels and so on... But during execution of program those are 0 or nulls.
Can anyone help me with this? I am unclear why this was working some while ago (I last worked on this code in March) and same code doesn't work anymore.
EDIT:
I found problem. First frame which is read from file is damaged or something, so I just waited for first correct frame to initialize my components.
This question can be closed.

Related

QT paly audio by QAudioDevidce can't connect to PulseAudioService

Like title, i'm trying to use Qt and FFmpeg to play audio. My code like this:
QAudioOutput *audio_output;
QIODevice *stream_out;
QAudioFormat audio_fmt;
audio_fmt.setSampleRate(44100);
audio_fmt.setChannelCount(2);
audio_fmt.setSampleSize(16);
audio_fmt.setCodec("audio/pcm");
audio_fmt.setByteOrder(QAudioFormat::LittleEndian);
audio_fmt.setSampleType(QAudioFormat::SignedInt);
QAudioDeviceInfo info = QAudioDeviceInfo::defaultOutputDevice();
if(!info.isFormatSupported(audio_fmt))
{
audio_fmt = info.nearestFormat(audio_fmt);
}
audio_output = new QAudioOutput(audio_fmt);
When i use QAudioDeviceInfo info = QAudioDeviceInfo::defaultOutputDevice()
i get PulseAudioService: pa_context_connect() failed error.
So how can i fix it?
By the way, i'm using Ubuntu 16.04 and Qt 5.14.2, and i have add 'mutilmedia' to Qt pro file
I checked my Qt file ,and i have audio dir in plugins, it's not lib problem. Also, i read this post ,but i don't know how to fix it, anybody have idea? Thank you guys,and my English is bad, wish you can understand what do i say.

How can I fix this gTTS issue?

I have the following code with gTTS
from gtts import gTTS
obj = gTTS(text = "Hello there", lang = 'en')
obj.save("hello.mp3")
For some reason, however, (I'm using version 2.2.3, python 3.7.3) it was working just fine
a few days ago on my raspberry pi 4 Model B and it suddenly stopped again.
I fixed it before by upgrading to a newer version (2.2.3 in my case), but
it worked for a few months and now I'm having the same issue with it as before -
when saving the mp3 file it takes too much time, whereas when it was working fine it took no more than a second (now it needs at least a minute or more), before you say it, it is not due to my internet connection. I've tried everything on the internet and I can't seem to find a solution that works 100% forever, on windows it works just fine and the mp3 file is saved instantly (same gTTS version), but on rpi it takes too much time when it should take no more than a second (and it worked that way until it magically stopped a few days ago).

ffpmeg - how to detect if video crop is completed?

Thanks in advance.
I'm trying to crop a .mp4 video using an ffmpeg binary (within the context of an electron-react-app).
(The binary is run in a child process using execFile() and outputs to a temp folder which is later deleted)
ffmpeg varies considerably in the time it takes to complete the creation of a cropped video file (1sec to 18sec) depending on the computer (mac vs Windows).
I need to read the cropped video file.
I've set up an event listener in the Main process of electron
if (!monitorCroppedFile) {
console.log(`${croppedFilePath} doesn't exist`);
} else {
console.log(`${croppedFilePath} exists !`)
...readFile...;
Once monitorCroppedFile = true I read it using fs.readfile().
The problem is that ffmpeg initally creates the cropped file path but it sometimes takes ages to complete the process of cropping.
This results in the read file often being blank (as the read is triggered on detecting the file path of the cropped file).
I've tried using -preset ultrafast in the ffmpeg arguments but this only improves things on Windows marginally.
The problem doesn't occur on Macs.
Can anybody suggest a possible solution ? Is there a way to detect when the crop is fully completed ?
Many thanks.
Add -progress FILE to your command where FILE should be a filename. ffmpeg will log processing status to that file. Search for the line progress=end in it. Once you find it, you can read the file.

Python Sounddevice Callback returning an array with zeros

I am trying the Python Sounddevice lib to stream audio from the microphone
self.audio_streamer = sd.Stream(device=self.input_device, channels=self.channels,
samplerate=self.sampling_rate, dtype='int16',
callback=self.update_audio_feed, blocksize=self.audio_block_size,
latency='low')```
def update_audio_feed(self, indata, outdata, frames, time, status):
print("update_audio_feed")
if status:
print(status, file=sys.stderr)
print(indata)
outdata.fill(0)
Output :
The indata is an array with 0's always from the callback.
update_audio_feed
[[0]
[0]
[0]
...
[0]
[0]
[0]]
Sounddevice is detectingt the mic fine but not getting the signal :
Device Info: {'name': 'MacBook Pro Microphone', 'hostapi': 0, 'max_input_channels': 1, 'max_output_channels': 0, 'default_low_input_latency': 0.04852607709750567, 'default_low_output_latency': 0.01, 'default_high_input_latency': 0.05868480725623583, 'default_high_output_latency': 0.1, 'default_samplerate': 44100.0}
Sampling rate: 44100.0
The issue on my mac was a security/ permissions issue . When I tried running the python script through Visual Studio Console it did not work... But when I tried the mac Terminal it prompted for the microphone and everything started to work..
More details here :
https://www.reddit.com/r/MacOS/comments/9lwyz0/mojave_not_privacy_settings_blocking_all_mic/
https://github.com/spatialaudio/python-sounddevice/issues/267
I've been using sounddevice without major issues on a number of Macs for a few months now.
Firstly, have you tried the wire.py example? That works out of the box for me.
Two things that I noticed in your code:
I haven't tried specifying the blocksize. I have only used the default value of 0. I could well believe that may be causing you issues.
You've specified a "low" latency Stream. At the very least on OSX10.13 this produces very unstable audio (lots of input underflows). If stable audio is important to you, I would recommend you consider latency options higher than "high". For reference, Audacity uses 100ms and obtains stable audio. Also, input underflows often mean indata is filled with zeros.
For those interested in this problem in the future, you may wish to look at the issue posted on sounddevice at GitHub.
I had the same issue on MacOS, but I was running the script from vscode. Actually vscode wouldn't ask for microphone permission, so it will assume it has this permission (which it didn't) and you will get an empty array.
Switched to running the script from terminal and everything changed, I got a permission request and everything went well.

How to capture still image from webcam on linux

I am trying to write a C++/Qt program for linux, where I take a still image photo from a webcam, make some transformations to a photo (cropping, resizing, etc.), and save it to a jpeg file.
But I have encountered some problems. The main problem is that standart UVC (usb video device class) linux driver currently does not support direct still image capture: http://www.ideasonboard.org/uvc/ .
So, there are two possible ways to capture still image. You can take one frame from the video stream from the camera, or you can take a separate photo, like a digital portable camera. The second way is not supported in linux uvc driver, so the first method is the only way. But the problem is, that if you want to take a frame from the video stream, the size of the photo can't be bigger than the size of video in the video preview window. So, if I want to take 2 megapixel photo, I must start videostream with the size 1600x1200, which is not so comfortable (At least, in Qt the size of the videostream depends on the videopreview window size).
I know that there is video for linux 2 API, which may be helpful in this task, but I don't know how to use it. I am currently learning gstreamer, but I can't now figure out how to do what I need using these tools.
So, I will appreciate any help. I think it is not a hard problem for people who know Linux, GStreamer, v4l2 API, and other linux-specific things.
By the way, the program will be used only with web-camera Logitech C270 HD.
Please, help me. I don't know what API or framework can help me do this. May be you know.
Unfortunately the C4V2 calls in opencv did not work for still image capture with any camera I have tried out of the box using the UVC driver.
To debug the issue I have been playing with trying to accomplish this with c code calling c4v2 directly.
I have been playing with the example code found here. It uses the method of pulling frames from the video stream.
You can compile it with:
gcc -O2 -Wall `pkg-config --cflags --libs libv4l2` filename.c -o filename
I have experimented with 3 logitech cameras. The best of the lot seems to be the Logitech C910. But even it has significant issues.
Here are the problems I have encountered trying to accomplish your same task with this code.
It works pretty much every time with width and height set to 1920x1080.
When I query other possibilities directly from the command line using for example:
v4l2-ctl --list-formats-ext
and I try some of the other "available" smaller sizes it hangs in the select waiting for the camera to release the buffer.
Also when I try to set other sizes directly from the command line using for example:
v4l2-ctl -v height=320 -v width=240 -v pixelformat=YUYV
Then check with
v4l2-ctl -V
I find that it returns the correct pixel format but quite often not the correct size.
Apparently this camera which is listed on the UVC site as being UVC and therefore v4l2 compatible is not up to snuff. I suspect it is just as bad for other cameras. The other two I tried were also listed as compatible on the site but had worse problems.
I did some more testing on the LogitechC910 after I posted this. I thought I would post the results in case it helps someone else out.
I wrote a script to test v4l2 grabber code mentioned above on all the formats the camera claims it supports when it is queried with v4l2 here are the results:
640x480 => Hangs on clearing buffer
160x120 => Works
176x144 => Works
320x176 => Works
320x240 => Works
432x240 => Works
352x288 => Works
544x288 => Works
640x360 => Works
752x416 => Hangs on clearing buffer
800x448 => Hangs on clearing buffer
864x480 => Works
960x544 => Works
1024x576 => Works
800x600 => Works
1184x656 => Works
960x720 => Works
1280x720 => Works
1392x768 => Works
1504x832 => Works
1600x896 => Works
1280x960 => Works
1712x960 => Works
1792x1008 => Works
1920x1080 => Works
1600x1200 => Works
2048x1536 => Works
2592x1944 => Hangs on clearing buffer.
It turns out that the default setting of 640x480 doesnt work and that is what trapped me and most others who have posted on message boards.
Since it is grabbing a video frame the first frame it grabs when starting up may have incorrect exposure (often black or close to it). I believe this is because since it is being used as a video camera it adjusts exposure as it goes and doesnt care about the first frames. I believe this also trapped me and other who saw the first frame as black or nearly black and thought it was some kind of error. Later frames have the correct exposure
It turns out that opencv with python wrappers works fine with this camera if you avoid the land mines listed above and ignore all the error messages. The error messages are due to the fact while the camera accepts v4l2 commands it doesnt respond correctly. So if you set the width it actually gets set correctly but it responds with an incorrect width.
To run under opencv with python wrappers you can do the following:
import cv2
import numpy
cap = cv2.VideoCapture(0) #ignore the errors
cap.set(3, 960) #Set the width important because the default will timeout
#ignore the error or false response
cap.set(4, 544) #Set the height ignore the errors
r, frame = cap.read()
cv2.imwrite("test.jpg", frame)
**Download And Install 'mplayer'**
mplayer -vo png -frames 1 tv://
mplayer -vo png -frames 1 tv://
might give a green screen output as the camera is not yet ready.
mplayer -vo png -frames 2 tv://
You can try increasing the number of frames and choose a number from which the camera gives correct images.
What about this program?
#include<opencv2/opencv.hpp>
using namespace cv;
int main()
{
VideoCapture webcam;
webcam.open(0);
Mat frame;
char key;
while(true)
{
webcam >> frame;
imshow("My Webcam",frame);
key = waitKey(10);
if(key=='s')
break;
}
imwrite("webcam_capture.jpg", frame);
webcam.release();
return 0;
}
This will capture a picture of maximum size allowed by your webcam. Now you can add effects or resize the captured image with Qt. And OpenCV is very very easy to integrate with Qt, :)

Resources