Chinaunix首页 | 论坛 | 博客
  • 博客访问: 631886
  • 博文数量: 1008
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 5175
  • 用 户 组: 普通用户
  • 注册时间: 2012-07-31 09:44
文章分类
文章存档

2012年(1008)

我的朋友

分类:

2012-08-01 11:07:30

原文地址:QT实现媒体播放器 作者:luozhiyong131

媒体播放器设计文档

一、功能概述:

文件格式:一般视频文件( *.vai *.rmvb)

基本功能:播放、停止、快进、快退

网络功能:从服务端下载、上传视频文件

播放模式:直接加载本地视频播放,从播放列表播放视频

二、功能具体实现:

2.1文件加载:

加载文件按键被触发,槽函数调用QFileDialog::getOpenFileName获得文件名

mediaObject->setCurrentSource(Phonon::MediaSource(filename));

对播放列表发出信号,更新播放列表

2.2播放功能

判断是否正在播放

a)如果没有播放调用play()函数进入播放,改变播放按钮状态显示为暂停

b)否则调用pause()暂停改变播放按钮状态显示

2.3快进、快退

调用seek(stime 5000) stime现在正在播放的时间,stime由定时器更新值

2.4停止

调用stop()clear()函数停止播放并释放资源

刷新显示屏(先关、再显示)

ui->frameVideo->close();

        ui->frameVideo->show();

2.5媒体库隐藏与显示

在主窗口构造函数中初始化媒体库但并不显示

当媒体库按钮按下调用媒体库显示函数show()

当按键再次按下关闭媒体库close()

2.6播放列表操作

播放列表操作采用数据库(QSqlTableModel)包括增、删、查

数据库初始化:在主程序中调用连接数据库函数,连接数据库并打开表

播放列表更新:加载文件时主窗口发出新增文件信号,这信号连接到数据库插入函数。

  文件下载完成时也会发出新增信号

播放列表删除: removeRow(curRow);  curRow所选中的行

播放列表Play:获得选中行的文件名 先获得选中行号currentIndex().row()

  查询数据库id 为row的信息得到文件名

  发出播放信号,主窗口播放文件

三、网络功能:

传输协议选用:TCP UPD FTP

分析:一个服务器发给多个客户端    

     传输数据比较多,文件比较大

  以上综合考虑所以选用TCP。因为TCP协议的程序使用的是客户端/服务器模式。所以需要单独设计服务器

QTcpSocket类来编写客户端程序,使用QTcpServer类编写服务器端程序。在服务器端进行端口的监听,一旦发现客户端的连接请求,利用自动发出newConnection()信号,关联这个信号到自己的槽函数,进行数据的发送。而在客户端,一旦有数据到来就会发出readyRead()信号,我们可以关联此信号,进行数据的接收。

编程模型

TCP服务器

 初始化套接字   绑定   监听   接受连接   阻塞直到客户连接到达   接收   发送   接收   关闭

TCP客户端

 初始化套接字   连接   发送   接收   关闭

A) 服务器设计:

a) 服务器功能:发送与接收数据

b) 服务器初始化:建立套接字、监听端口tcpServer.listen(QHostAddress::LocalHost,6666)等待客户端连接请求。初始化套接字,监听本地主机的一个端口,这里使用6666,然后关联newConnection()信号与自己写的acceptConnection()槽函数。一旦有客户端的连接请求,就会执行acceptConnection()函数,connect(&tcpServer,SIGNAL(newConnection()),this, SLOT(acceptConnection()));

C) 服务器接受端客户端连接请求,使用tcpServernextPendingConnection()函数来获取已经建立的连接的Tcp套接字,使用它来完成数据的发送、接收、异常处理操作

void Widget::acceptConnection() //接受连接

{

    tcpServerConnection = tcpServer.nextPendingConnection();

    connect(tcpServerConnection,SIGNAL(readyRead()),

            this, SLOT(updateServerProgress()));

    connect(tcpServerConnection, SIGNAL(error(QAbstractSocket::SocketError)),

            this, SLOT(displayError(QAbstractSocket::SocketError)));

    connect(tcpServerConnection,SIGNAL(bytesWritten(qint64)),

            this, SLOT(updateClientProgress(qint64)));

    ui->serverStatusLabel->setText(tr("接受连接"));

    tcpServer.close();

}

数据收发

A)服务端传给客户端:发送

1、获得要传输的文件: wfileName = QFileDialog::getOpenFileName(this);

2.调用发送函数:

为保证在客户端能接收到完整的文件,在数据流的最开始写入文件的大小、文件名等信息,这样客户端就可以根据大小信息来判断是否接受到了完整的文件。

发文件大概流程

先进行文件头结构的发送,当发送成功时就服务器会发出bytesWritten(qint64)信号,这updateClientProgress(qint64 numBytes)函数中进行文件数据的传输和进度条的更新。这里使用了一个loadSize变量(始化为4*10244字节),它的作用是,将整个大的文件分成很多小的部分进行发送,每部分为4字节。而当连接出现问题时就会发出error(QAbstractSocket::SocketError)信号,这时就会执行displayError()函数。

B服务端接收客户端文件

客户端有上传请求,服务端发出读信号

接收文件头结构头,获得文件的大小,文件名并创建文件;

接收数据、写入文件、更新进度条

接收数据完成

客户端收发数据与服务端基本类似(这里不再重复)

客户端手动下载资源

实现原理;

1、 客户端给服务器端发送下载请求

2、 服务端对下载请求作出回应,发送文件给客户端

3、 客户端接收数据

程序中的出现过的Bug

问题:客户端与服务端相互进行文件传送只能传一次,第二次传输有问题

解决:1、先解决服务端至客户端连续文件的传输

服务器端:发送文件完清空初始化控制传输条件的关键变量值

客户端:接收文件前初始化控制接收条件关键变量值

2、解决客户端至服务端连续文件的传输

客户端:发文件完初始化控制控制传输条件关键变量值

服务器端:接收文件完清空初始化控制接收条件的关键变量值

 功能演示.rar    QT项目.rar   

阅读(156) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~