如何在QT中显示自定义AVPlayer视频层

时间:2018-12-12 12:11:57

标签: ios objective-c qt avfoundation avplayer

我正在使用自定义QT组件来创建自己的iOS播放器(因为我需要DRM的默认MediaPlayer的修改版)。

到目前为止,我设法创建了一个简单的组件。

头文件:

#include <QObject>
#include <QQuickItem>

class CustomPlayer : public QQuickItem
{
    Q_OBJECT

private:

public:
    CustomPlayer(QQuickItem *parent = 0);
    Q_INVOKABLE void play();
};

mm文件:

#include <Foundation/Foundation.h>
#include <sys/utsname.h>
#include <UIKit/UIKit.h>
#include <AVFoundation/AVFoundation.h>
#include <AVKit/AVKit.h>

#include "customplayer.h"


//===================================

CustomPlayer::CustomPlayer(QQuickItem *parent)
    : QQuickItem(parent)
{
}

void CustomPlayer::play()
{
    AVPlayer *_player;
    AVURLAsset *_asset;
    AVPlayerItem *_playerItem;

    _player = [[AVPlayer alloc] init];

    NSURL *baseURL = [[NSURL alloc] initWithString: @"http://devimages.apple.com/iphone/samples/bipbop/bipbopall.m3u8"];

    _asset = [AVURLAsset assetWithURL:baseURL];

    _playerItem = [AVPlayerItem playerItemWithAsset: _asset];

    [_player replaceCurrentItemWithPlayerItem:_playerItem];

    [_player play];
}

它仍然是一个很粗糙的版本,但是有了它我可以在我的QML代码中使用CustomPlayer。 但是我正在努力的是为视频渲染创建一个图层。

我试图通过查看qtmultimedia中的源代码来了解QT是如何创建MediaPlayer的,但我很难理解它。 如何为播放器创建一个输出,使其显示在CustomPlayer组件中?

1 个答案:

答案 0 :(得分:0)

这是C ++代码(父类是QQuickPaintedItem):

// header

class VideoViewport : public QQuickPaintedItem
{
    Q_OBJECT
public:
    explicit VideoViewport(QQuickItem *parent = nullptr);

    void paint(QPainter *painter) override;
public slots:
    void updateImage(const QImage& frame);
private:
    QImage _currentImage;
};

// impementation in the *.cpp file
VideoViewport::VideoViewport(QQuickItem *parent):
    QQuickPaintedItem(parent)
{
}

void VideoViewport::paint(QPainter *painter)
{
    QSizeF _size = _currentImage.size();
    _size.scale(this->boundingRect().size(), Qt::KeepAspectRatio);
    QRectF output = QRectF(QPointF(0, 0), _size);
    output.moveCenter(boundingRect().center());
    painter->drawImage(output, _currentImage);
}

void VideoViewport::updateImage(const QImage &frame)
{
    _currentImage = frame;
    update();
}

在main.cpp

int main(...)
{
    //...
    qmlRegisterType<VideoViewport>("your.path.to.widgets", 1, 0 , "VideoViewport");
    //...
}