I do not want to stop the program's flow since the mp3 are like a voice over to support the user during the use of the application.
I'm using C++ and Ubuntu 18.04 and WxWidgets 3.1.
I tried to use libvlc and to write a class to play and stop the mp3; I've read that libvlc already integrates asynchronous methods but if I try to play a file, the program stops until the mp3 is not finished. So I decided to use threads.
It works, but when I try to stop the mp3, I get a segmentation fault.
This is my current code (rePlay is the class to play the music, firstpanel.cpp is the first panel where I play the music and secondpanel.cpp is the second panel where I want to send the signal to stop the music).
At the moment, the music correctly starts in firstpanel, but when I try to stop it from the second panel, I get the segment fault error.
I hope you can help me! I do not need to use libvlc necessarily, amy other solution is OK.
Code: Select all
// replay.h
#include <vlc/vlc.h>
class rePlay
{
public:
rePlay();
virtual ~rePlay();
void play_mp3(const char*);
void stop_mp3();
protected:
libvlc_instance_t *inst;
libvlc_media_player_t *mp;
libvlc_media_t *m;
private:
};
// rePlay.cpp
#include "rePlay.h"
#include <vlc/vlc.h>
rePlay::rePlay()
{
//ctor
}
rePlay::~rePlay()
{
//dtor
}
void rePlay::play_mp3(const char* path){
// load the vlc engine
inst = libvlc_new(0, NULL);
printf("apro il file %d\n", inst);
// create a new item
m = libvlc_media_new_path(inst, path);
// create a media play playing environment
mp = libvlc_media_player_new_from_media(m);
// no need to keep the media now
libvlc_media_release(m);
// play the media_player
libvlc_media_player_play(mp);
printf("Done.\n");
}
void rePlay::stop_mp3(){
// stop playing
libvlc_media_player_stop(mp);
// free the media_player
libvlc_media_player_release(mp);
libvlc_release(inst);
}
// firstpanel.h
class firstpanel: public wxPanel
{
public:
firstpanel(wxWindow* parent, Isola02Frame*, wxWindowID id=wxID_ANY,const wxPoint& pos=wxDefaultPosition,const wxSize& size=wxDefaultSize);
virtual ~firstpanel();
void checkValue(wxCommandEvent& event);
void check_cf(wxTimerEvent& event);
rePlay *mp3_apertura_porta = new rePlay(); // <-- I DECLARED THE pointer here
//(*Declarations(firstpanel)
wxStaticText* assistenza;
wxStaticText* first_panel;
wxStaticText* identificazione;
wxTextCtrl* tessera;
//*)
...
}
// firstpanel.cpp
std::thread second = std::thread([this]() noexcept {
this->mp3_apertura_porta->play_mp3("/home/robodyne/Project/audio/scegli-rifiuto.mp3"); });
second.join();
// secondpanel.cpp
void secondpanel::OnBitmapButton2Click(wxCommandEvent& event)
{
firstpanel *ptr;
ptr->mp3_apertura_porta->stop_mp3();
}
// secondpanel.h
class secondpanel: public wxPanel
{
public:
secondpanel(wxWindow* parent, Isola02Frame*, wxWindowID id=wxID_ANY,const wxPoint& pos=wxDefaultPosition,const wxSize& size=wxDefaultSize);
virtual ~secondpanel();
//(*Declarations(secondpanel)
wxBitmapButton* BitmapButton2;
wxBitmapButton* BitmapButton3;
wxBitmapButton* BitmapButton4;
wxBitmapButton* BitmapButton5;
wxBitmapButton* BitmapButton6;
wxBitmapButton* plastica;
wxStaticText* selezione_tipologia;
//*)
protected:
Isola02Frame *pointer;
//(*Identifiers(secondpanel)
static const long ID_BITMAPBUTTON1;
static const long ID_BITMAPBUTTON2;
static const long ID_BITMAPBUTTON3;
static const long ID_BITMAPBUTTON4;
static const long ID_BITMAPBUTTON5;
static const long ID_BITMAPBUTTON6;
static const long ID_STATICTEXT1;
//*)
private:
//(*Handlers(secondpanel)
void OnplasticaClick(wxCommandEvent& event);
void OnBitmapButton2Click(wxCommandEvent& event);
//*)
DECLARE_EVENT_TABLE()
};