Difference between revisions of "Development/Tutorials/Phonon/Simple Media Player"

Jump to: navigation, search
m (Text replace - "</code>" to "</syntaxhighlight>")
(add simple media player example from kde git, remove not be used parts from original tutorial, new ones need to be written)
Line 1: Line 1:
 
<!-- TODO: Link classes to apidox -->
 
<!-- TODO: Link classes to apidox -->
 +
==Abstract==
 
One of the primary target audiences of Phonon is simple multimedia players. After following this tutorial, you will be able to create a minimal multimedia player application using C++, Phonon, Qt, and CMake.
 
One of the primary target audiences of Phonon is simple multimedia players. After following this tutorial, you will be able to create a minimal multimedia player application using C++, Phonon, Qt, and CMake.
 +
[[image:Phonon-tutorial2.png|frame|center]]
  
= Starting =
+
==The Code==
Phonon's native language is C++. For other languages such as Python, Ruby, QML, etc, have a look at [[Development/Tutorials/Phonon/Language Bindings|our page covering other language bindings]] for language-specific information. Other than what is noted on that page, Phonon's API is 100% the same for all platforms.
+
 
+
 
This simple player application will consist of two .cpp files, one .h, and a CMakeLists.txt:
 
This simple player application will consist of two .cpp files, one .h, and a CMakeLists.txt:
  
* main.cpp
+
===main.cpp===
* player.cpp
+
Like all executable binaries, a <tt>main()</tt> function is needed. We implement a simple one in main.cpp:
* player.h
+
<syntaxhighlight lang="cpp-qt">
* CMakeLists.txt
+
#include <KAboutData>
 +
#include <KApplication>
 +
#include <KCmdLineArgs>
  
We first begin by writing a CMakeLists.txt file which is used by CMake to generate a proper Makefile for building:
+
#include "mainwindow.h"
  
<syntaxhighlight lang="text">
+
int main(int argc, char *argv[])
cmake_minimum_required(VERSION 2.6.2 FATAL_ERROR)
+
{
 +
  KAboutData aboutData("basicaudioplayer", 0,
 +
                      ki18n("Basic Audio Player"), "1.0",
 +
                      ki18n("A basic audio player using Phonon."),
 +
                      KAboutData::License_BSD,
 +
                      ki18n("Copyright (c) 2011-2013 Jon Ander Peñalba <jonan88@gmail.com>"));
 +
  KCmdLineArgs::init(argc, argv, &aboutData);
 +
  KApplication app;
  
find_package(Qt4 REQUIRED)
+
  MainWindow *window = new MainWindow();
include(${QT_USE_FILE})
+
  window->show();
  
find_package(Phonon REQUIRED)
+
  return app.exec();
 +
}
 +
</syntaxhighlight>
  
add_definitions(${QT_DEFINITIONS} ${PHONON_DEFINITIONS})
+
===mainwindow.h===
include_directories(${QT_INCLUDES} ${CMAKE_CURRENT_BINARY_DIR} ${PHONON_INCLUDES})
+
Now that we have a working build environment, real work can begin. The first step is to build a simple GUI. In this simple player, the GUI will be nothing more than a simple QWidget with a few children. No fancy designer .ui files, no complicated file browser, no exciting features.
  
set(simpleplayer_SRCS
+
Copy the following code into your mainwindow.h:
    main.cpp
+
<syntaxhighlight lang="cpp-qt">
)
+
#ifndef MAINWINDOW_H
 +
#define MAINWINDOW_H
  
qt4_automoc(${simpleplayer_SRCS})
+
#include <KMainWindow>
  
add_executable(simpleplayer ${simpleplayer_SRCS} ${simpleplayer_MOC_SRCS})
+
class KLineEdit;
target_link_libraries(simpleplayer ${QT_LIBRARIES} phonon)
+
class KPushButton;
</syntaxhighlight>
+
  
First, we define a minimum cmake version. Without it, you'll get an ugly but harmless warning. Next, the CMake script looks for the Qt package and sets up the build environment to use it. Finally, we define a variable to contain our list of sources then run Qt's moc tool, build an executable, and link it against phonon. If you are unfamiliar with moc, please refresh your memory with [http://doc.qt.nokia.com/latest/ the official Qt documentation]
+
namespace Phonon {
 
+
class MediaObject;
Like all executable binaries, a <tt>main()</tt> function is needed. We implement a simple one in main.cpp:
+
}
<syntaxhighlight lang="text">
+
#include <QtGui/QApplication>
+
  
int main(int argc, char **argv)
+
class MainWindow : public KMainWindow
 
{
 
{
     QApplication app(argc, argv);
+
     Q_OBJECT
     return app.exec();
+
 
}
+
  public:
 +
    MainWindow(QWidget *parent=0);
 +
 
 +
  private slots:
 +
     void openFile();
 +
 
 +
  private:
 +
    Phonon::MediaObject *media;
 +
 
 +
    KLineEdit *file_name;
 +
    KPushButton *file_button;
 +
};
 +
 
 +
#endif // MAINWINDOW_H
 
</syntaxhighlight>
 
</syntaxhighlight>
  
player.cpp and player.h will be written in the next section. You can build the project with <tt>'cmake /path/to/sources/ && make'</tt>. Running the <tt>simpleplayer</tt> binary won't do anything other than sit in the Qt event loop, waiting for the last window to be closed. Since no windows were created, it waits forever.
+
===mainwindow.cpp===
 +
<syntaxhighlight lang="cpp-qt">
 +
#include "mainwindow.h"
  
= Building a GUI =
+
#include <QtGui/QHBoxLayout>
  
Now that we have a working build environment, real work can begin. The first step is to build a simple GUI. In this simple player, the GUI will be nothing more than a simple QWidget with a few children. No fancy designer .ui files, no complicated file browser, no exciting features.
+
#include <KApplication>
 +
#include <KFileDialog>
 +
#include <KLineEdit>
 +
#include <KPushButton>
  
Copy the following code into your player.h:
+
#include <Phonon/AudioOutput>
<syntaxhighlight lang="text">
+
#include <Phonon/MediaObject>
#ifndef PLAYER_H
+
#include <Phonon/SeekSlider>
#define PLAYER_H
+
#include <Phonon/VolumeSlider>
  
#include <QtGui/QWidget>
+
MainWindow::MainWindow(QWidget *parent)
#include <phonon/Global>
+
    : KMainWindow(parent)
 +
{
 +
  // Create the widgets
  
class QPushButton;
+
  // File selector
namespace Phonon {
+
  file_name = new KLineEdit("Open an audio file", this);
    class MediaObject;
+
  file_button = new KPushButton("Open", this);
    class Mrl;
+
  file_name->setEnabled(false);
}
+
  connect(file_button, SIGNAL(clicked()), this, SLOT(openFile()));
class Player : public QWidget {
+
  
Q_OBJECT
+
  // Audio control
 +
  Phonon::SeekSlider *seek = new Phonon::SeekSlider(this);
 +
  KPushButton *play_button = new KPushButton("Play", this);
 +
  KPushButton *pause_button = new KPushButton("Pause", this);
 +
  KPushButton *stop_button = new KPushButton("Stop", this);
 +
  Phonon::VolumeSlider *volume = new Phonon::VolumeSlider(this);
 +
  volume->setOrientation(Qt::Vertical);
  
public:
+
  // Define the layout
    Player(QWidget *parent = 0, Qt::WindowFlags flag = 0);
+
  // File stuff
 +
  QHBoxLayout *file_layout = new QHBoxLayout(this);
 +
  file_layout->addWidget(file_name);
 +
  file_layout->addWidget(file_button);
  
public slots:
+
  // Buttons
    void load(const Phonon::Mrl &url);
+
  QHBoxLayout *button_layout = new QHBoxLayout(this);
    void load();
+
  button_layout->addWidget(play_button);
 +
  button_layout->addWidget(pause_button);
 +
  button_layout->addWidget(stop_button);
  
private slots:
+
  // Seek slider
    void mediaStateChanged(Phonon::State newState, Phonon::State oldState);
+
  QVBoxLayout *left_layout = new QVBoxLayout(this);
    void playPause();
+
  left_layout->addWidget(seek);
 +
  left_layout->addLayout(button_layout);
  
private:
+
  // Volume slider
    Phonon::MediaObject *m_media;
+
  QHBoxLayout *audio_layout = new QHBoxLayout(this);
    QPushButton *m_playPause;
+
  audio_layout->addLayout(left_layout);
    QPushButton *m_stop;
+
  audio_layout->addWidget(volume);
  
};
+
  // Let's bring it all together
 +
  QWidget *central_widget = new QWidget(this);
 +
  QVBoxLayout *central_layout = new QVBoxLayout(this);
 +
  central_layout->addLayout(file_layout);
 +
  central_layout->addLayout(audio_layout);
 +
  central_widget->setLayout(central_layout);
 +
  setCentralWidget(central_widget);
 +
 
 +
  // Create the media and define the output
 +
  media = new Phonon::MediaObject(this);
 +
  Phonon::AudioOutput *output = new Phonon::AudioOutput(Phonon::MusicCategory, this);
 +
  Phonon::createPath(media, output);
 +
 
 +
  // Connect the widgets to the audio
 +
  seek->setMediaObject(media);
 +
  volume->setAudioOutput(output);
 +
  connect(play_button, SIGNAL(clicked()), media, SLOT(play()));
 +
  connect(pause_button, SIGNAL(clicked()), media, SLOT(pause()));
 +
  connect(stop_button, SIGNAL(clicked()), media, SLOT(stop()));
 +
}
 +
 
 +
void MainWindow::openFile()
 +
{
 +
  QString file = KFileDialog::getOpenFileName();
 +
  file_name->setText(file);
 +
  media->setCurrentSource(file);
 +
  media->play();
 +
}
 +
</syntaxhighlight>
 +
 
 +
==Build==
 +
===CMakeLists.txt===
 +
We first begin by writing a CMakeLists.txt file which is used by CMake to generate a proper Makefile for building:
  
#endif //PLAYER_H
+
<syntaxhighlight lang="cmake">
 +
project (phonon_tutorial2)
 +
find_package(KDE4 REQUIRED)
 +
include (KDE4Defaults)
 +
include_directories(${KDE4_INCLUDES})
 +
set(phonon_tutorial2_SRCS main.cpp mainwindow.cpp)
 +
kde4_add_executable(phonon_tutorial2 ${phonon_tutorial2_SRCS})
 +
target_link_libraries(phonon_tutorial2 ${KDE4_KDEUI_LIBS} ${PHONON_LIBS} ${KDE4_KIO_LIBS})
 +
install(TARGETS phonon_tutorial2  ${INSTALL_TARGETS_DEFAULT_ARGS})
 
</syntaxhighlight>
 
</syntaxhighlight>
  
The code defines a Player class that inherits from QWidget. It contains a reference to a phonon MediaObject along with two push buttons. Two slots to handle updating the user interface in response to playback state changes and button presses are present. In addition, it contains a method to load a specific URL (later passed in via the command line) and another one to prompt the user for a file to load.
+
Here we link our example against phonon.
  
<syntaxhighlight lang="text">
+
===Make And Run===
TODO - tdfischer Jun 7, 2011
+
<syntaxhighlight lang="bash">
 +
cmake . && make && ./phonon_tutorial2
 
</syntaxhighlight>
 
</syntaxhighlight>

Revision as of 16:12, 10 May 2013

Contents

Abstract

One of the primary target audiences of Phonon is simple multimedia players. After following this tutorial, you will be able to create a minimal multimedia player application using C++, Phonon, Qt, and CMake.

Phonon-tutorial2.png

The Code

This simple player application will consist of two .cpp files, one .h, and a CMakeLists.txt:

main.cpp

Like all executable binaries, a main() function is needed. We implement a simple one in main.cpp:

#include <KAboutData>
#include <KApplication>
#include <KCmdLineArgs>
 
#include "mainwindow.h"
 
int main(int argc, char *argv[])
{
  KAboutData aboutData("basicaudioplayer", 0,
                       ki18n("Basic Audio Player"), "1.0",
                       ki18n("A basic audio player using Phonon."),
                       KAboutData::License_BSD,
                       ki18n("Copyright (c) 2011-2013 Jon Ander Peñalba <jonan88@gmail.com>"));
  KCmdLineArgs::init(argc, argv, &aboutData);
  KApplication app;
 
  MainWindow *window = new MainWindow();
  window->show();
 
  return app.exec();
}

mainwindow.h

Now that we have a working build environment, real work can begin. The first step is to build a simple GUI. In this simple player, the GUI will be nothing more than a simple QWidget with a few children. No fancy designer .ui files, no complicated file browser, no exciting features.

Copy the following code into your mainwindow.h:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
 
#include <KMainWindow>
 
class KLineEdit;
class KPushButton;
 
namespace Phonon {
class MediaObject;
}
 
class MainWindow : public KMainWindow
{
    Q_OBJECT
 
  public:
    MainWindow(QWidget *parent=0);
 
  private slots:
    void openFile();
 
  private:
    Phonon::MediaObject *media;
 
    KLineEdit *file_name;
    KPushButton *file_button;
};
 
#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
 
#include <QtGui/QHBoxLayout>
 
#include <KApplication>
#include <KFileDialog>
#include <KLineEdit>
#include <KPushButton>
 
#include <Phonon/AudioOutput>
#include <Phonon/MediaObject>
#include <Phonon/SeekSlider>
#include <Phonon/VolumeSlider>
 
MainWindow::MainWindow(QWidget *parent)
    : KMainWindow(parent)
{
  // Create the widgets
 
  // File selector
  file_name = new KLineEdit("Open an audio file", this);
  file_button = new KPushButton("Open", this);
  file_name->setEnabled(false);
  connect(file_button, SIGNAL(clicked()), this, SLOT(openFile()));
 
  // Audio control
  Phonon::SeekSlider *seek = new Phonon::SeekSlider(this);
  KPushButton *play_button = new KPushButton("Play", this);
  KPushButton *pause_button = new KPushButton("Pause", this);
  KPushButton *stop_button = new KPushButton("Stop", this);
  Phonon::VolumeSlider *volume = new Phonon::VolumeSlider(this);
  volume->setOrientation(Qt::Vertical);
 
  // Define the layout
  // File stuff
  QHBoxLayout *file_layout = new QHBoxLayout(this);
  file_layout->addWidget(file_name);
  file_layout->addWidget(file_button);
 
  // Buttons
  QHBoxLayout *button_layout = new QHBoxLayout(this);
  button_layout->addWidget(play_button);
  button_layout->addWidget(pause_button);
  button_layout->addWidget(stop_button);
 
  // Seek slider
  QVBoxLayout *left_layout = new QVBoxLayout(this);
  left_layout->addWidget(seek);
  left_layout->addLayout(button_layout);
 
  // Volume slider
  QHBoxLayout *audio_layout = new QHBoxLayout(this);
  audio_layout->addLayout(left_layout);
  audio_layout->addWidget(volume);
 
  // Let's bring it all together
  QWidget *central_widget = new QWidget(this);
  QVBoxLayout *central_layout = new QVBoxLayout(this);
  central_layout->addLayout(file_layout);
  central_layout->addLayout(audio_layout);
  central_widget->setLayout(central_layout);
  setCentralWidget(central_widget);
 
  // Create the media and define the output
  media = new Phonon::MediaObject(this);
  Phonon::AudioOutput *output = new Phonon::AudioOutput(Phonon::MusicCategory, this);
  Phonon::createPath(media, output);
 
  // Connect the widgets to the audio
  seek->setMediaObject(media);
  volume->setAudioOutput(output);
  connect(play_button, SIGNAL(clicked()), media, SLOT(play()));
  connect(pause_button, SIGNAL(clicked()), media, SLOT(pause()));
  connect(stop_button, SIGNAL(clicked()), media, SLOT(stop()));
}
 
void MainWindow::openFile()
{
  QString file = KFileDialog::getOpenFileName();
  file_name->setText(file);
  media->setCurrentSource(file);
  media->play();
}

Build

CMakeLists.txt

We first begin by writing a CMakeLists.txt file which is used by CMake to generate a proper Makefile for building:

project (phonon_tutorial2)
find_package(KDE4 REQUIRED)
include (KDE4Defaults)
include_directories(${KDE4_INCLUDES})
set(phonon_tutorial2_SRCS main.cpp mainwindow.cpp)
kde4_add_executable(phonon_tutorial2 ${phonon_tutorial2_SRCS})
target_link_libraries(phonon_tutorial2 ${KDE4_KDEUI_LIBS} ${PHONON_LIBS} ${KDE4_KIO_LIBS})
install(TARGETS phonon_tutorial2  ${INSTALL_TARGETS_DEFAULT_ARGS})

Here we link our example against phonon.

Make And Run

cmake . && make && ./phonon_tutorial2

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V.Legal