为什么使用 Ubuntu Touch 应用程序在桌面上运行的时候在手机上听不到声音?

为什么使用 Ubuntu Touch 应用程序在桌面上运行的时候在手机上听不到声音?

我正在开发一个 Ubuntu Touch 应用程序。该应用程序需要播放声音。我使用 C++ 中的 QtMultimedia 进行声音播放。声音在 PC 上播放正常,但在手机上播放不正常。

奇怪的是,当使用 QtCreator 和 Build → Ubuntu → Run Application on Device 在手机上运行应用程序时,声音播放正常。当在手机上安装应用程序并使用 Build → Ubuntu → Install Application on Device,然后从手机的 Dash 运行它时,听不到声音。我的开发环境是 Ubuntu 14.04,手机运行 Ubuntu Touch (trusty) v250。

作为参考,这里是我用于实际播放的代码片段:

Playlist::Playlist(QObject *parent) :
    QObject(parent),
    m_trackListHandler(new TrackListHandler()),
    m_playlist(new QMediaPlaylist()),
    m_player(new QMediaPlayer()),
    m_currentIndex(0)
{
    m_player->setPlaylist(m_playlist);
}

void Playlist::playTrack(int index)
{
    if (index < m_trackList.count())
    {
        m_playlist->setCurrentIndex(index);
        m_currentIndex = index;
        m_player->play();

        emit playbackStarted(m_trackList.at(index));
    }
}

void Playlist::resumePlayback()
{
    // ...
}

void Playlist::pause()
{
    // ...
}

void Playlist::nextTrack()
{
    // ...
}

void Playlist::previousTrack()
{
    // ...
}

void Playlist::appendTrack(PTrack track)
{
    // ...
}

void Playlist::appendAndPlay(PTrack track)
{
    // ...
}

playlist.h 的完整源代码:

#include "playlist.h"

#include "album.h"
#include "track.h"
#include "tracklisthandler.h"

#include <QMediaPlaylist>
#include <QMediaPlayer>

#include "logger.h"

Playlist & Playlist::instance()
{
    static Playlist instance;

    return instance;
}

Playlist::Playlist(QObject *parent) :
    QObject(parent),
    m_trackListHandler(new TrackListHandler()),
    m_playlist(new QMediaPlaylist()),
    m_player(new QMediaPlayer()),
    m_currentIndex(0)
{
    LOG_INFO << "called";
    m_player->setPlaylist(m_playlist);
}

Playlist::~Playlist()
{
    delete m_trackListHandler;
    delete m_playlist;
    delete m_player;
}


void Playlist::playTrack(int index)
{
    LOG_INFO << "called";

    if (index < m_trackList.count())
    {
        m_playlist->setCurrentIndex(index);
        m_currentIndex = index;
        m_player->play();

        emit playbackStarted(m_trackList.at(index));
    }
}

void Playlist::resumePlayback()
{
    LOG_INFO << "called";
    m_player->play();

    emit playbackStarted(m_trackList.at(m_currentIndex));
}

void Playlist::pause()
{
    LOG_INFO << "called";
    m_player->pause();
}

void Playlist::nextTrack()
{
    LOG_INFO << "called";
    int nextIndex = m_currentIndex + 1;

    if (nextIndex >= m_trackList.count())
    {
        nextIndex = 0;
    }

    m_currentIndex = nextIndex;
    m_playlist->setCurrentIndex(m_currentIndex);
    m_player->play();

    emit playbackStarted(m_trackList.at(m_currentIndex));
}

void Playlist::previousTrack()
{
    LOG_INFO << "called";
    int previousIndex = m_currentIndex - 1;

    if (previousIndex <= 0)
    {
        previousIndex = m_trackList.count() - 1;
    }

    m_currentIndex = previousIndex;
    m_playlist->setCurrentIndex(m_currentIndex);
    m_player->play();

    emit playbackStarted(m_trackList.at(m_currentIndex));
}

void Playlist::appendTrack(PTrack track)
{
    LOG_INFO << "called";
    m_trackList.append(track);
    m_playlist->addMedia(m_trackListHandler->streamUrl(track));

    emit playlistChanged();
}

void Playlist::appendAndPlay(PTrack track)
{
    LOG_INFO << "called";
    m_trackList.append(track);
    m_playlist->addMedia(m_trackListHandler->streamUrl(track));
    m_currentIndex = m_trackList.indexOf(track);
    m_playlist->setCurrentIndex(m_currentIndex);
    m_player->play();

    emit playlistChanged();
    emit playbackStarted(track);
}

TrackList Playlist::tracks() const
{
    return m_trackList;
}

void Playlist::clear()
{
    m_trackList.clear();
    m_playlist->clear();
}

int Playlist::count() const
{
    return m_trackList.count();
}

Playlist.cpp 文件:

#ifndef PLAYLIST_H
#define PLAYLIST_H

#include <QObject>

#include "common.h"

class TrackListHandler;
class QMediaPlaylist;
class QMediaPlayer;

class Playlist : public QObject
{
    Q_OBJECT

public:
    static Playlist &instance();

public:
    void playTrack(int index);
    void resumePlayback();
    void pause();
    void nextTrack();
    void previousTrack();

    void appendAndPlay(PTrack track);
    void appendTrack(PTrack track);

    TrackList tracks() const;
    void clear();
    int count() const;

signals:
    void playlistChanged();
    void playbackStarted(PTrack track);

private:
    TrackList m_trackList;
    TrackListHandler *m_trackListHandler;
    QMediaPlaylist *m_playlist;
    QMediaPlayer *m_player;
    int m_currentIndex;

private:
    Playlist(QObject *parent = 0);
    virtual ~Playlist();

    Playlist(Playlist const &): QObject(0) { }

    Playlist &operator =(Playlist const &) { return *this; }
};

#endif // PLAYLIST_H

应用日志:

playlist.cpp 111 void Playlist::appendAndPlay(PTrack) INFO: called 
shm_open() failed: Permission denied
Failed to create secure directory (/run/user/32011/pulse): Permission denied
Cannot connect to server socket err = No such file or directory
Cannot connect to server request channel
jack server is not running or cannot be started
GStreamer; Unable to pause - "http://192.168.0.110:4040/rest/stream.view?&v=1.10.2&c=ro.kicsyromy.playsonic&id=396" 
shm_open() failed: Permission denied
Failed to create secure directory (/run/user/32011/pulse): Permission denied
Cannot connect to server socket err = No such file or directory
Cannot connect to server request channel
jack server is not running or cannot be started
GStreamer; Unable to play - "http://192.168.0.110:4040/rest/stream.view?&v=1.10.2&c=ro.kicsyromy.playsonic&id=396" 
playlistmodel.cpp 33 virtual QVariant PlaylistModel::data(const QModelIndex&, int) const INFO: called for index 0 
playlistmodel.cpp 33 virtual QVariant PlaylistModel::data(const QModelIndex&, int) const INFO: called for index 0 
playlistmodel.cpp 33 virtual QVariant PlaylistModel::data(const QModelIndex&, int) const INFO: called for index 0 
Error: "Could not initialize supporting library." 

manifest.json 文件:

{
    "architecture": "all",
    "description": "Player client for Subsonic and Subsonic API compatible servers",
    "framework": "ubuntu-sdk-13.10",
    "hooks": {
        "Playsonic": {
            "apparmor": "Playsonic.json",
            "desktop": "Playsonic.desktop"
        }
    },
    "maintainer": "Romeo Calota",
    "name": "ro.kicsyromy.playsonic",
    "title": "Playsonic",
    "version": "0.1"
}

AppArmor 配置文件:

{
    "policy_groups": [
        "networking",
        "audio",
        "accounts",
        "audio",
        "calendar",
        "camera",
        "connectivity",
        "contacts",
        "content_exchange",
        "content_exchange_source",
        "friends",
        "history",
        "location",
        "microphone",
        "music_files",
        "music_files_read",
        "networking",
        "picture_files",
        "picture_files_read",
        "sensors",
        "usermetrics",
        "video",
        "video_files",
        "video_files_read"
    ],
    "policy_version": 1
}

答案1

您是否已将“音频”添加到安全策略中?转到 QtCreator 中的“发布”部分,然后在“安全策略组”列表下单击“+”按钮并添加“音频”。然后尝试再次在设备上安装该包,看看它是否有效。

我怀疑这是因为当在设备上运行代码时,QtCreator 会将文件复制到临时位置并从命令行启动它们,因此它们不受限制地运行。但是当从 click 包安装它时,它将受到该包中定义的安全策略的限制。

http://developer.ubuntu.com/publish/apps/security-policy-for-click-packages/了解有关监禁和安全政策的更多信息。

相关内容