简单的多屏播放器示例(vlc+qt)

简单的多屏播放器示例(vlc+qt)

介绍

  • 简单的多屏播放器
  • 最多同时播放16个视频
  • 支持本地文件和rtsp、rtmp等流媒体播放
  • VS2015工程,依赖Qt+VLC
  • 练手作品

截图


下载

程序:download.csdn.net/detail/u014755412/9908787

源码:github.com/FutaAlice/QtPlayer


代码分析

IMediaPlayer是为规定接口的基类

提供了播放和控制的几个常用函数

其中打开媒体部分拆分为了OpenURL和OpenFile,并在cpp中实现

若为Windows环境,则对QFileDialog获取的路径进行替换

/*******************************************************************
IMediaPlayer.h(接口类)
构造时传入QWidget*
调用OpenFile或OpenURL或Open打开文件并渲染窗体
*******************************************************************/

#ifndef IMEDIAPLAYER_H
#define IMEDIAPLAYER_H

class QWidget;
class IMediaPlayer
{
public:
    IMediaPlayer(QWidget* pWidget);
    virtual ~IMediaPlayer();

    virtual bool OpenFile();
    virtual bool OpenURL(const char* url);

    virtual bool Open(const char* url) = 0;
    virtual bool Play() = 0;
    virtual void Pause() = 0;
    virtual void Stop() = 0;
    virtual void ChangeVolume(int vol) = 0;

protected:
    QWidget* m_pWidget;
};

#endif // IMEDIAPLAYER_H
/*******************************************************************
IMediaPlayer.cpp(接口类)
*******************************************************************/
#include "IMediaPlayer.h"
#include <QtWidgets/QWidget>
#include <QtWidgets/qfiledialog.h>

// Windows环境下进行字符替换
static void StrReplace(QString& str)
{
#if defined(Q_OS_MAC)       // Mac
#elif defined(Q_OS_UNIX)    // Linux
#elif defined(Q_OS_WIN)     // Windows
    str = str.replace(QRegExp("/"), "\\");
#endif
}

IMediaPlayer::IMediaPlayer(QWidget* pWidget)
    : m_pWidget(pWidget)
{
}

IMediaPlayer::~IMediaPlayer()
{
}

bool IMediaPlayer::OpenFile()
{
    QString fileOpen = QFileDialog::getOpenFileName(NULL, "Load a file", "~");
    if (!fileOpen.isEmpty())
    {
        StrReplace(fileOpen);
        return Open(fileOpen.toUtf8().constData());
    }
    else
        return false;
}

bool IMediaPlayer::OpenURL(const char * url)
{
    return Open(url);
}


之后新建一个派生自IMediaPlayer的类:VlcMediaPlayer,

并使用libvlc实现其基类中的纯虚函数实现视频的播放

/*******************************************************************
VlcMediaPlayer.h
使用libvlc实现的IMediaPlayer
构造时传入QWidget*
调用OpenFile或OpenURL或Open打开文件并渲染窗体
例如:
    QWidget* pWidget = new QOpenGLWidget();
    pWidget->show();
    auto player = new VlcMediaPlayer(pWidget);
    player->Open("test.hevc");
*******************************************************************/

#ifndef VLCMEDIAPLAYER_H
#define VLCMEDIAPLAYER_H

#include "IMediaPlayer.h"

struct libvlc_media_player_t;
struct libvlc_instance_t;
class VlcMediaPlayer :
    public IMediaPlayer
{
public:
    VlcMediaPlayer(QWidget* pWidget);
    ~VlcMediaPlayer();

    // 禁用拷贝构造和赋值
    VlcMediaPlayer(const VlcMediaPlayer&) = delete;
    VlcMediaPlayer& operator=(VlcMediaPlayer&) = delete;

    // Control
    virtual bool Open(const char* url);
    virtual bool Play();
    virtual void Pause();
    virtual void Stop();
    virtual void ChangeVolume(int vol) ;

private:
    // 播放器对象
    libvlc_media_player_t *m_pVlcPlayer;

private:
    // libvlc实例,所有窗体的渲染共用一个
    static libvlc_instance_t *s_pVlcInstance;
    static unsigned int s_ref;
};

#endif // VLCMEDIAPLAYER_H
/*******************************************************************
VlcMediaPlayer.cpp
libvlc播放视频的实现
*******************************************************************/
#include "VlcMediaPlayer.h"
#include <assert.h>
#include <QtWidgets/QWidget>

# ifdef __cplusplus
extern "C" {
# endif
#include <vlc/vlc.h>
# ifdef __cplusplus
}
# endif

#if defined(Q_OS_MAC)       // Mac
// TODO
#elif defined(Q_OS_UNIX)    // Linux
#pragma comment(lib, "libvlc.a")
#elif defined(Q_OS_WIN)     // Windows
#pragma comment(lib, "libvlc.lib")
#endif

unsigned int VlcMediaPlayer::s_ref = 0;
libvlc_instance_t *VlcMediaPlayer::s_pVlcInstance = NULL;

VlcMediaPlayer::VlcMediaPlayer(QWidget* pWidget)
    : IMediaPlayer(pWidget)
    , m_pVlcPlayer(NULL)
{
    /* Initialize libVLC */
    if (0 == s_ref++)
    {
        s_pVlcInstance = libvlc_new(0, NULL);
        if (NULL == s_pVlcInstance)
        {
            assert(false);
        }
    }
}

VlcMediaPlayer::~VlcMediaPlayer()
{
    if (0 == --s_ref)
    {
        libvlc_release(s_pVlcInstance);
    }
}

bool VlcMediaPlayer::Open(const char *url)
{
    /* Stop if something is playing */
    Stop();

    auto funcOpen = libvlc_media_new_path;
    if (QString(url).startsWith("rtsp://") ||
        QString(url).startsWith("rtmp://") ||
        QString(url).startsWith("rtp://") ||
        QString(url).startsWith("tcp://") ||
        QString(url).startsWith("udp://") ||
        QString(url).startsWith("ftp://") ||
        QString(url).startsWith("http://") ||
        QString(url).startsWith("https://"))
    {
        funcOpen = libvlc_media_new_location;
    }

    /* Create a new Media */
    libvlc_media_t *vlcMedia = funcOpen(s_pVlcInstance, url);
    /* Fail to open url*/
    if (!vlcMedia)
    {
        return false;
    }

    if (QString(url).endsWith(".hevc"))
        libvlc_media_add_option(vlcMedia, ":demux=hevc");
    else if (QString(url).endsWith("rtsp"))
        libvlc_media_add_option(vlcMedia, ":rtsp-tcp");

    /* Create a new libvlc player */
    m_pVlcPlayer = libvlc_media_player_new_from_media(vlcMedia);

    /* Release the media */
    libvlc_media_release(vlcMedia);

    return Play();
}

bool VlcMediaPlayer::Play()
{
    /* Integrate the video in the interface */
#if defined(Q_OS_MAC)
    libvlc_media_player_set_nsobject(m_pVlcPlayer, (void*)m_pWidget->winId());
#elif defined(Q_OS_UNIX)
    libvlc_media_player_set_xwindow(m_pVlcPlayer, m_pWidget->winId());
#elif defined(Q_OS_WIN)
    libvlc_media_player_set_hwnd(m_pVlcPlayer, (void*)m_pWidget->winId());
#endif

    /* And start playback */
    int vlc_ret = libvlc_media_player_play(m_pVlcPlayer);
    if (0 == vlc_ret)
        return true;
    else
        return false;
}

void VlcMediaPlayer::Pause()
{
    if (m_pVlcPlayer && libvlc_media_player_is_playing(m_pVlcPlayer))
    {
        libvlc_media_player_pause(m_pVlcPlayer);
    }
}

void VlcMediaPlayer::Stop()
{
    if (m_pVlcPlayer)
    {
        /* stop the media player */
        libvlc_media_player_stop(m_pVlcPlayer);

        /* release the media player */
        libvlc_media_player_release(m_pVlcPlayer);

        /* Reset application values */
        m_pVlcPlayer = NULL;
    }
}

void VlcMediaPlayer::ChangeVolume(int vol)
{
    if (m_pVlcPlayer)
    {
        libvlc_audio_set_volume(m_pVlcPlayer, vol);
    }
}


界面部分,

响应界面按钮点击的消息和调整窗体大小的消息,

并且调用VlcMediaPlayer添加播放视频的小窗口

/*******************************************************************
QtPlayer.h
*******************************************************************/
#pragma once

#include <QtWidgets/QWidget>
#include "ui_QtPlayer.h"

struct libvlc_media_player_t;
class QtPlayer : public QWidget
{
    Q_OBJECT
public:
    QtPlayer(QWidget *parent = Q_NULLPTR);
    void resizeEvent(QResizeEvent* e);

private slots:
    void openFile();
    void openURL();

private:
    Ui::QtPlayerClass ui;
    QWidget* m_pSubWidgets[16];
};
/*******************************************************************
QtPlayer.cpp
*******************************************************************/
#include "QtPlayer.h"
#include "VlcMediaPlayer.h"

QtPlayer::QtPlayer(QWidget *parent)
    : QWidget(parent)
{
    ui.setupUi(this);

    memset(m_pSubWidgets, NULL, sizeof(m_pSubWidgets));
}

void QtPlayer::openFile()
{
    int w = width() / 4, h = (height() - 24) / 4;
    for (int i = 0; i < 16; ++i)
    {
        if (m_pSubWidgets[i] == NULL)
        {
            m_pSubWidgets[i] = new QWidget(this);
            auto player = new VlcMediaPlayer(m_pSubWidgets[i]);

            // 打开成功
            if (player->OpenFile())
            {
                resizeEvent(NULL);
                m_pSubWidgets[i]->show();
            }
            else
            {
                delete player;
                delete m_pSubWidgets[i];
                m_pSubWidgets[i] = NULL;
            }
            break;
        }
    }
}

void QtPlayer::resizeEvent(QResizeEvent *e)
{
    int w = width() / 4, h = (height() - 24) / 4;
    for (int i = 0; i < 16; ++i)
    {
        if (NULL == m_pSubWidgets[i])
            continue;
        m_pSubWidgets[i]->resize(QSize(w, h));
        m_pSubWidgets[i]->move(QPoint((i % 4) * w, (i / 4) * h));
    }
    QPoint pos = ui.btnOpenFile->pos();
    pos.setY(height() - 24);
    ui.btnOpenFile->move(pos);

    pos = ui.btnOpenURL->pos();
    pos.setY(height() - 24);
    ui.btnOpenURL->move(pos);

    pos = ui.lineEdit->pos();
    pos.setY(height() - 24);
    ui.lineEdit->move(pos);
}

void QtPlayer::openURL()
{
    int w = width() / 4, h = height() / 4;
    for (int i = 0; i < 16; ++i)
    {
        if (m_pSubWidgets[i] == NULL)
        {
            m_pSubWidgets[i] = new QWidget(this);
            auto player = new VlcMediaPlayer(m_pSubWidgets[i]);
            // 打开成功
            if (player->OpenURL(ui.lineEdit->text().toUtf8().constData()))
            {
                resizeEvent(NULL);
                m_pSubWidgets[i]->show();
            }
            else
            {
                delete player;
                delete m_pSubWidgets[i];
                m_pSubWidgets[i] = NULL;
            }
            break;
        }
    }
}

原文地址:https://www.cnblogs.com/FutaAlice/p/8454187.html

时间: 2024-09-30 14:10:28

简单的多屏播放器示例(vlc+qt)的相关文章

【源码分享】mui实现简单的手机音乐播放器

mui实现简单的手机音乐播放器 最近先来无事,我用mui写了一个可以跨页面控制的音乐播放器.主要功能有上一曲,下一曲,播放,暂停,感兴趣的可以继续看下去. 说的总是不实在,直接上源码,有兴趣的可以读下注释. 1首页代码 ①首页的html代码 1 <a> 2 <i id="bofang" class="iconfont icon-play-o"></i> <!--就是一个播放按钮没啥特殊的--> 3 </a>

h5-自定义视屏播放器

1.html代码 1 <h3 class="playerTitle">视屏播放器</h3> 2 <div class="player"> 3 <video src="../mp4/chrome.mp4"></video> 4 <div class="controls"> 5 <!--比如这里的开始和暂停图标就是font-awesome.css文件中的

libvlc —— 播放器示例程序[C++代码实现攫取 RGB图像 和 PCM音频 数据功能]

在我以前的实际项目中,曾利用 libvlc 去解码音视频媒体数据(如 RTSP.本地文件 等),通过其提供的回调函数接口,攫取 RGB图像 进行图像分析,如 人脸识别.运动检测 等一类的产品应用.除此之外,只要提供适当的 MRL,配合选项参数,VLC 还可以进行屏幕录制.摄像头图像采集.麦克风音频采集 等功能. 我在网上参看过很多人提供的示例源码,实现流程都很初潜,只适合当作学习的 Demo 来看,与实际的项目应用还有很多问题要解决.为此,在这里公开我封装 libvlc 的 C++ 类,方便TA

做个简单的本地弹幕播放器

前言 本文仅仅是做一个简单的弹幕播放器 本文弹幕播放器仅仅是演示一下发送弹幕功能 请跳转本文底部的在线调试代码进行调试 最终实现效果如下: Okay.首先你得找到一个弹幕开源库就是这个啦:https://github.com/jabbany/CommentCoreLibrary 其次你得准备好一个HTML文件 准备完后lets do it 更多内容请见原文链接:http://www.gbtags.com/gb/share/5769.htm 引入两个重要的弹幕开源库文件 这里用了我blog的文件

Android中使用SurfaceView+MediaPlayer+自定义的MediaController实现自定义的视屏播放器

效果图如下: (PS本来是要给大家穿gif动态图的,无奈太大了,没法上传) 功能实现:暂停,播放,快进,快退,全屏,退出全屏,等基本功能 实现的思路: 在主布局中放置一个SurfaceView,在SurfaceView中放置一个MediaPlayer ,在其下方自定义一个MediaController,不过也不能称之为MediaController,使用的是PupupWindow来实现的,在PupupWindow布局中放置几个textView,Button,最重要的使我们的SeekBar控件,创

iOS 简单实用的音乐播放器,少年,自己做个歌单吧。。。。。。

我也不知道为什么突然会想写一下音乐播放器的,感觉应该挺好的玩,自己把自己喜欢的歌曲导出来,用程序加载跑 起来,那歌听起来必定很带感啊......不过那首Love Story被我听了无数遍......听吐了 各位看官有兴趣也可以听听.其实前期准备是很坑爹的,找歌词真的蛋疼啊. 废话不多说,老规矩,看成品先: 尼玛这东西占得空间太大了,录不了太多...... 先介绍吧 首先 做个播放器的界面出来,上面是个tableView来加载歌词,底部两个Slider,一个声音,一个进度,最底下三个Button.

ios 简单的本地音乐播放器

一.导入资源文件 二.新建一个控制器,继承于UITableViewController,用来展示播放列表 1.播放列表的实现 @interface MusicListViewController (){ //定义一个播放列表数组 NSMutableArray *musicList; } - (void)viewDidLoad { [super viewDidLoad]; //调用解析文件类方法,得到播放列表 musicList=[MusicModel allMusics]; } - (NSInt

简单的HTML5音乐播放器(带歌词滚动)

首先需要整理好lrc格式的歌词放到script标签中以供程序处理.然后把音乐链接放到audio的src属性里就可以了. 源码: HTML部分 1 <div class="container"> 2 <audio id="player" src="test.mp3" loop controls preload></audio> 3 <div id="lrcArea"></di

Plyr – 简单,灵活的 HTML5 媒体播放器

Plyr 是一个简单的 HTML5 媒体播放器,包含自定义的控制选项和 WebVTT 字幕.它是只支持现代浏览器,轻量,方便和可定制的媒体播放器.还有的标题和屏幕阅读器的全面支持. 在线演示      源码下载 您可能感兴趣的相关文章 网站开发中很有用的 jQuery 效果[附源码] 分享35个让人惊讶的 CSS3 动画效果演示 十分惊艳的8个 HTML5 & JavaScript 特效 Web 开发中很实用的10个效果[源码下载] 12款经典的白富美型 jQuery 图片轮播插件 本文链接:P