@ -22,6 +22,7 @@
// TQt
# include <tqtooltip.h>
# include <tqlabel.h>
# include <tqslider.h>
# include <tqpushbutton.h>
# include <tqfile.h>
@ -30,6 +31,8 @@
# include <tdeparts/genericfactory.h>
# include <tdeglobalsettings.h>
# include <tdeio/netaccess.h>
# include <tdemessagebox.h>
# include <tdefiledialog.h>
# include <tdeaction.h>
# include <kmimetype.h>
# include <tdemessagebox.h>
@ -50,7 +53,8 @@ K_EXPORT_COMPONENT_FACTORY (libmpvpart, MpvPartFactory);
MpvPart : : MpvPart ( TQWidget * parentWidget , const char * widgetName , TQObject * parent , const char * name , const TQStringList & /*args*/ )
: KaffeinePart ( parent , name ? name : " MpvPart " ) ,
m_current ( 0 ) ,
m_seeking ( false )
m_seeking ( false ) ,
m_recordFilePath ( )
{
// Create an instance of this class
setInstance ( MpvPartFactory : : instance ( ) ) ;
@ -153,9 +157,25 @@ void MpvPart::initActions()
m_volume = new TQSlider ( 0 , 100 , 10 , 100 , TQt : : Horizontal , 0 ) ;
connect ( m_volume , SIGNAL ( sliderMoved ( int ) ) , this , SLOT ( slotSetVolume ( int ) ) ) ;
KWidgetAction * volAction = new KWidgetAction ( m_volume , i18n ( " Volume " ) , 0 , 0 , 0 , actionCollection ( ) , " player_volume " ) ;
new KWidgetAction ( m_volume , i18n ( " Volume " ) , 0 , 0 , 0 , actionCollection ( ) , " player_volume " ) ;
/*** Stream recording toolbar ***/
m_recordAction = new TDEToggleAction ( i18n ( " &Record stream " ) , " player_record " , Key_R , this , SLOT ( slotToggleRecording ( ) ) , actionCollection ( ) , " record_toggle " ) ;
new TDEAction ( i18n ( " Set recording file " ) , " document-open " , 0 , this , SLOT ( slotSetRecordingFile ( ) ) , actionCollection ( ) , " record_open " ) ;
m_recordFile = new TQLabel ( 0 ) ;
new KWidgetAction ( m_recordFile , i18n ( " Recording file " ) , 0 , 0 , 0 , actionCollection ( ) , " record_file " ) ;
updateRecordFileLabel ( ) ;
resetTime ( ) ;
stateChanged ( " disable_all " ) ;
}
void MpvPart : : showError ( TQString text , TQString caption ) {
KMessageBox : : sorry ( 0 , text , caption ) ;
}
void MpvPart : : showDetailedError ( TQString text , TQString details , TQString caption ) {
KMessageBox : : detailedSorry ( 0 , text , details , caption ) ;
}
// Custom events dispatched from mpv event thread are handled here
@ -192,6 +212,18 @@ void MpvPart::customEvent(TQCustomEvent *event) {
KMessageBox : : detailedError ( nullptr , i18n ( " Cannot play file. " ) , eofe - > error ( ) ) ;
}
}
else if ( event - > type ( ) = = MPVPART_EVENT_ERROR ) {
slotPause ( true ) ;
MpvErrorEvent * ee = ( MpvErrorEvent * ) event ;
if ( ee - > details ( ) . isEmpty ( ) ) {
showError ( ee - > text ( ) , ee - > caption ( ) ) ;
}
else {
showDetailedError ( ee - > text ( ) , ee - > details ( ) , ee - > caption ( ) ) ;
}
}
}
bool MpvPart : : openURL ( const MRL & mrl ) {
@ -304,11 +336,14 @@ void MpvPart::slotPlay() {
else {
emit signalRequestCurrentTrack ( ) ;
}
stateChanged ( isStream ( ) ? " playing_stream " : " playing_file " ) ;
}
void MpvPart : : slotPause ( bool pause ) {
int value = pause ? 1 : 0 ;
mpv_set_property ( m_mpv , " pause " , MPV_FORMAT_FLAG , & value ) ;
stateChanged ( pause ? " paused " : ( isStream ( ) ? " playing_stream " : " playing_file " ) ) ;
}
void MpvPart : : slotTogglePause ( ) {
@ -347,6 +382,14 @@ bool MpvPart::isMute() {
return ( bool ) result ;
}
bool MpvPart : : isStream ( ) {
TQString proto = m_mrl . kurl ( ) . protocol ( ) ;
if ( proto . startsWith ( " http " ) | | proto . startsWith ( " rtsp " ) ) {
return true ;
}
return false ;
}
void MpvPart : : resetTime ( ) {
m_playtime - > setText ( " 0:00:00 " ) ;
m_position - > setValue ( 0 ) ;
@ -415,6 +458,7 @@ void MpvPart::slotStop() {
if ( isPlaying ( ) ) {
const char * args [ ] = { " stop " , nullptr } ;
mpv_command_async ( m_mpv , 0 , args ) ;
stateChanged ( " not_playing " ) ;
}
}
@ -423,4 +467,64 @@ void MpvPart::slotMute() {
mpv_set_property ( m_mpv , " ao-mute " , MPV_FORMAT_FLAG , & value ) ;
}
void MpvPart : : slotToggleRecording ( ) {
if ( m_recordAction - > isChecked ( ) ) {
startRecording ( ) ;
}
else {
stopRecording ( ) ;
}
}
void MpvPart : : startRecording ( ) {
// Ensure we have an out file and start recording
if ( m_recordFilePath . isEmpty ( ) ) {
slotSetRecordingFile ( ) ;
}
if ( m_recordFilePath . isEmpty ( ) ) {
m_recordAction - > setChecked ( false ) ;
return ;
}
mpv_set_property_string ( m_mpv , " stream-record " , m_recordFilePath . local8Bit ( ) ) ;
m_recordAction - > setChecked ( true ) ;
}
void MpvPart : : stopRecording ( ) {
mpv_set_property_string ( m_mpv , " stream-record " , " " ) ;
m_recordAction - > setChecked ( false ) ;
}
void MpvPart : : slotSetRecordingFile ( ) {
if ( m_recordAction - > isChecked ( ) & & ! m_recordFilePath . isEmpty ( ) ) {
if ( ! KMessageBox : : warningContinueCancel ( 0 ,
i18n ( " Changing the recording file will stop the recording process. " ) ,
i18n ( " Recording in progress " ) ) = = KMessageBox : : Continue )
{
return ;
}
}
m_recordFilePath = KFileDialog : : getSaveFileName (
TQString : : null ,
" *.mkv| " + i18n ( " Matroska file (*.mkv) " ) + " \n " +
" *.ogg| " + i18n ( " OGG media (*.ogg) " ) + " \n " +
" *.mp4| " + i18n ( " MPEG-4 video (*.mp4) " ) + " \n " +
" *.mpeg| " + i18n ( " MPEG video (*.mpeg) " ) + " \n " +
" *.avi| " + i18n ( " Microsoft AVI video (*.avi) " ) + " \n " +
" *.mp3| " + i18n ( " MPEG Layer 3 audio (*.mp3) " ) + " \n " +
" *.mp2| " + i18n ( " MPEG Layer 2 audio (*.mp2) " ) + " \n " +
" *.flac| " + i18n ( " FLAC audio (*.flac) " ) + " \n " ,
0 , i18n ( " Select file name for saved recording " ) ) ;
updateRecordFileLabel ( ) ;
}
void MpvPart : : updateRecordFileLabel ( ) {
m_recordFile - > setText (
m_recordFilePath . isEmpty ( )
? i18n ( " No output file " )
: m_recordFilePath
) ;
}
# include "libmpv_part.moc"