forked from yuan631111976/qtavplayer
-
Notifications
You must be signed in to change notification settings - Fork 0
/
AVPlayer.h
252 lines (212 loc) · 7.16 KB
/
AVPlayer.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
#ifndef AVPLAYER_H
#define AVPLAYER_H
#include <QtQml/QQmlParserStatus>
#include <QAudioOutput>
#include <QBuffer>
#include "AVDecoder.h"
#include "AVDefine.h"
#include "AVThread.h"
#include "AVMediaCallback.h"
class AVTimer;
class AVPlayer : public QObject , public AVMediaCallback ,public QQmlParserStatus
{
Q_OBJECT
Q_INTERFACES(QQmlParserStatus)
Q_PROPERTY(QString source READ source WRITE setSource NOTIFY sourceChanged)
Q_PROPERTY(bool autoLoad READ autoLoad WRITE setAutoLoad NOTIFY autoLoadChanged)
Q_PROPERTY(bool autoPlay READ autoPlay WRITE setAutoPlay NOTIFY autoPlayChanged)
Q_PROPERTY(bool hasAudio READ hasAudio NOTIFY hasAudioChanged)
Q_PROPERTY(bool hasVideo READ hasVideo NOTIFY hasVideoChanged)
Q_PROPERTY(int status READ status NOTIFY statusChanged)
Q_PROPERTY(bool renderFirstFrame READ renderFirstFrame WRITE setRenderFirstFrame) //加载后,是否渲染第一帧
Q_PROPERTY(int volume READ volume WRITE setVolume NOTIFY volumeChanged)
Q_PROPERTY(int pos READ pos WRITE seek NOTIFY positionChanged)
Q_PROPERTY(int duration READ duration NOTIFY durationChanged)
GENERATE_QML_NOSET_PROPERTY(sourceWidth,int) //原视屏的宽度
GENERATE_QML_NOSET_PROPERTY(sourceHeight,int)//原视屏的高度
GENERATE_QML_PROPERTY(preview,bool)//是否是预览
GENERATE_QML_PROPERTY(playSpeedRate,int)//播放速率,参数为AVDefine.PlaySpeedRate
GENERATE_QML_PROPERTY(accompany,bool)//是否启用伴唱 //true : 伴唱 | false : 原唱 ,默认为false
GENERATE_QML_PROPERTY(channelLayout,int)//AVDefine.AVChannelLayout
GENERATE_QML_PROPERTY(kdMode,int)//AVDefine.AVKDMode
GENERATE_QML_PROPERTY(minimumBufferSize,int)//缓冲区最小长度 默认5000毫秒,每次缓冲时,最少有3000毫秒的数据,才能开始播放 ,(设置此值时,如果底于3000,则为3000)
GENERATE_QML_PROPERTY(maximumBufferSize,int)//缓冲区最大长度 默认为 1000 * 10 (10秒钟)
GENERATE_QML_NOSET_PROPERTY(bufferedSize,int)//已经缓冲了多少时间的数据
GENERATE_QML_PROPERTY(decodecMode,int)//解码模式 AVDefine.AVDecodeMode
GENERATE_QML_NOSET_PROPERTY(supportDecodecModeList,QVector<int>)//当前视频支持的解码模式列表
GENERATE_GET_PROPERTY_CHANGED(sourceWidth,int)
GENERATE_GET_PROPERTY_CHANGED(sourceHeight,int)
GENERATE_GET_SET_PROPERTY_CHANGED_IMPL_SET(preview,bool)
GENERATE_GET_SET_PROPERTY_CHANGED_NO_IMPL(playSpeedRate,int)
GENERATE_GET_SET_PROPERTY_CHANGED_NO_IMPL(accompany,bool)
GENERATE_GET_SET_PROPERTY_CHANGED_NO_IMPL(channelLayout,int)
GENERATE_GET_SET_PROPERTY_CHANGED(kdMode,int)
GENERATE_GET_SET_PROPERTY_CHANGED(minimumBufferSize,int)
GENERATE_GET_SET_PROPERTY_CHANGED(maximumBufferSize,int)
GENERATE_GET_PROPERTY_CHANGED(bufferedSize,int)
GENERATE_GET_SET_PROPERTY_CHANGED_NO_IMPL(decodecMode,int)
GENERATE_GET_PROPERTY_CHANGED_NO_IMPL(supportDecodecModeList,QVector<int>)
public:
AVPlayer();
~AVPlayer();
QString source() const;
void setSource(const QString&);
bool autoLoad() const;
void setAutoLoad(bool);
bool autoPlay() const;
void setAutoPlay(bool);
bool hasAudio() const;
bool hasVideo() const;
int status() const;
bool renderFirstFrame() const;
void setRenderFirstFrame(bool);
int volume() const;
void setVolume(int vol);
void slotSetPlayRate(int);
int pos() const;
int duration() const;
VideoFormat *getRenderData();
AVDefine::AVPlayState getPlaybackState();
//QQmlParserStatus
virtual void classBegin();
virtual void componentComplete();
//////
public slots:
void play();
void pause();
void stop();
void restart();
void seek(int time);
void showFrameByPosition(int time); //显示指定位置的帧
public :
void seekImpl(int time);
//avmediacallback实现
public :
void mediaUpdateAudioFormat(const QAudioFormat&);
void mediaUpdateAudioFrame(const QByteArray &);
void mediaUpdateVideoFrame(void*);
void mediaDurationChanged(int);
void mediaStatusChanged(AVDefine::AVMediaStatus);
void mediaHasAudioChanged();
void mediaHasVideoChanged();
void mediaCanRenderFirstFrame();
void mediaUpdateBufferSize(int time){mbufferedSize = time;emit bufferedSizeChanged();}
signals :
void durationChanged();
void positionChanged();
void sourceChanged();
void autoLoadChanged();
void autoPlayChanged();
void hasAudioChanged();
void hasVideoChanged();
void statusChanged();
void volumeChanged();
void playStatusChanged();
void updateVideoFrame(VideoFormat*);
void playCompleted(); //播放完成
//更新音频频谱
void updateSpectrum();
public :
void requestRender();
void requestAudioData();
private :
void wakeupPlayer();
void setIsPaused(bool);
bool getIsPaused();
void setIsPlaying(bool);
bool getIsPlaying();
private:
AVDecoder *mDecoder;
AVDefine::AVMediaStatus mStatus;
AVDefine::AVSynchMode mSynchMode;
bool mAutoLoad;
bool mAutoPlay;
bool mRrnderFirstFrame;
float mVolume;
int mDuration;
int mPos;
int mSeekTime;
bool mIsSeeked;//是否拖动完成
bool mIsAudioWaiting;
QMutex mIsSeekedMutex;
QString mSource;
/** 组件是否加载完成 */
bool mComplete;
/** 视频播放控制线程 */
AVThread mThread;
AVThread mThread2;
AVTimer *mAudioTimer;
QMutex mAudioMutex;
QAudioOutput* mAudio;
QIODevice *mAudioBuffer;
QMutex mAudioBufferMutex;
int mLastTime;
bool mIsDestroy;
bool mIsPaused;
bool mIsPlaying;
bool mIsSetPlayRate;
bool mIsSetPlayRateBeforeIsPaused;
bool mIsClickedPlay;
QMutex mStatusMutex;
QWaitCondition mCondition;
QMutex mMutex;
/** 播放状态 */
AVDefine::AVPlayState mPlaybackState;
VideoFormat *mRenderData;
};
class AVPlayerTask : public Task{
public :
~AVPlayerTask(){}
enum AVPlayerTaskCommand{
AVPlayerTaskCommand_Render,
AVPlayerTaskCommand_Seek ,
AVPlayerTaskCommand_SetPlayRate
};
AVPlayerTask(AVPlayer *player,AVPlayerTaskCommand command,double param = 0):
mPlayer(player),command(command),param(param){this->type = (int)command;}
protected :
/** 线程实现 */
virtual void run();
private :
AVPlayer *mPlayer;
AVPlayerTaskCommand command;
double param;
};
class AVTimer : public QThread{
public :
AVTimer(AVPlayer *player) : mIsRunning(true),mPlayer(player){
start();
}
~AVTimer(){
mPlayer = NULL;
stop();
quit();
wait(100);
terminate();
}
virtual void run(){
while(mIsRunning){
if(mPlayer != NULL)
mPlayer->requestAudioData();
mMutex.lock();
mCondition.wait(&mMutex,20);
mMutex.unlock();
}
}
void begin(){
if(mPlayer != NULL && mPlayer->hasAudio()){
mIsRunning = true;
start();
}
}
void stop(){
mIsRunning = false;
mCondition.wakeAll();
}
private :
bool mIsRunning;
QWaitCondition mCondition;
QMutex mMutex;
AVPlayer *mPlayer;
};
#endif // AVPLAYER_H