1.创建Qt项目,选择编译器为Android_for_armeabi_v7。
2.使用之前编译好的ffmpeg头文件和库文件
a.在项目目录创建ffmpeg目录,目录里面包含include目录和lib目录,分别为ffmpeg的头文件和静态库文件所在目录
b.把ffmpeg\lib\libavcodec.a ffmpeg\lib\libavformat.a ffmpeg\lib\libavutil.a ffmpeg\lib\libswscale.a拷贝到 Qt目录\Qt5.3.1\5.3\android_armv7\lib目录下面
c.修改ffmpeg\include\libavutil\common.h 增加一行 #define UINT64_C(value) __CONCAT(value, ULL)
3.编辑项目文件
QT += core gui widgets
HEADERS += video.h videodec.h
SOURCES += main.cpp video.cpp videodec.cpp
INCLUDEPATH += ./ffmpeg/include #头文件路径
DEFINES += UINT64_C #增加定义
LIBS += -L./ffmpeg/lib -lavcodec -lavformat -lswscale -lavutil # -lavutil 放在最后面
4.编译、发布到android手机。
付源码:
ffmpeg.pro
QT += core gui widgets
HEADERS += \
video.h \
videodec.h
SOURCES += \
main.cpp \
video.cpp \
videodec.cpp
INCLUDEPATH += ./ffmpeg/include
DEFINES += UINT64_C
LIBS += -L./ffmpeg/lib -lavcodec -lavformat -lswscale -lavutil
main.cpp
#include "video.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.showMaximized();
return a.exec();
}
video.h
#ifndef VIDEO_H
#define VIDEO_H
#include <QThread>
#include <QWidget>
#include <QDebug>
#include <QImage>
#include <QPixmap>
#include <QPushButton>
#include <QLineEdit>
#include <QLabel>
#include "videodec.h"
class Video;
class MainWindow : public QWidget
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
private:
QPushButton *playButton;
QPushButton *browseButton;
QLineEdit *fileNameEdit;
QLabel *fileLabel;
Video *video;
private:
void setupUI();
private slots:
void onVideoPlay();
void onBrowseMP4();
};
class Video : public QWidget
{
Q_OBJECT
public:
explicit Video(QWidget *parent = 0);
~Video();
private:
QThread *videoDecThread;
VideoDec *videoDec;
protected:
void paintEvent(QPaintEvent *event);
signals:
void init();
void play();
void setFileName(QString);
public slots:
void showVideo(const QImage &img);
void onVideoPlay();
void onBrowseMP4(QString fileName);
};
#endif // VIDEO_H
video.cpp
#include "video.h"
#include <QPainter>
#include <QHBoxLayout>
#include <QFileDialog>
#include <QApplication>
static QImage showImage;
Video::Video(QWidget *parent) : QWidget(parent)
{
videoDecThread = new QThread(this);
videoDec = new VideoDec;
videoDec->moveToThread(videoDecThread);
videoDecThread->start();
connect(this, SIGNAL(init()), videoDec, SLOT(init()));
connect(this, SIGNAL(play()), videoDec, SLOT(play()));
connect(this, SIGNAL(setFileName(QString)), videoDec, SLOT(setFileName(QString)));
connect(videoDec, SIGNAL(SendImage(QImage)), this, SLOT(showVideo(QImage)));
}
Video::~Video()
{
}
void Video::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
QRectF target(0, 0, width(), height());
QRectF source(0.0, 0.0, width(), height());
painter.drawImage(target, showImage, source);
}
void Video::onVideoPlay()
{
emit init();
emit play();
}
void Video::onBrowseMP4(QString fileName)
{
emit setFileName(fileName);
}
void Video::showVideo(const QImage &img)
{
showImage = img;
update();
// QPixmap pix;
// pix = pix.fromImage(img).scaledToWidth(ui->VideoShow->width());
}
MainWindow::MainWindow(QWidget *parent) : QWidget(parent)
{
setupUI();
}
void MainWindow::setupUI()
{
fileLabel = new QLabel("File:", this);
fileNameEdit = new QLineEdit(this);
playButton = new QPushButton("Play", this);
connect(playButton, SIGNAL(clicked()), this, SLOT(onVideoPlay()));
browseButton = new QPushButton("Browse", this);
connect(browseButton, SIGNAL(clicked()), this, SLOT(onBrowseMP4()));
video = new Video(this);
QHBoxLayout *toolLayout = new QHBoxLayout;
toolLayout->addWidget(fileLabel);
toolLayout->addWidget(fileNameEdit);
toolLayout->addWidget(browseButton);
toolLayout->addWidget(playButton);
QVBoxLayout *mainLayout = new QVBoxLayout;
mainLayout->addLayout(toolLayout);
mainLayout->addWidget(video);
setLayout(mainLayout);
}
void MainWindow::onVideoPlay()
{
video->onVideoPlay();
}
void MainWindow::onBrowseMP4()
{
QString dir = QApplication::applicationDirPath();
QString fileName = QFileDialog::getOpenFileName(this, tr("Select a image file"), dir, tr("Image Files (*.*)"));
if (!fileName.isEmpty())
{
fileNameEdit->setText(fileName);
video->onBrowseMP4(fileName);
}
}
videodec.h
#ifndef VIDEODEC_H
#define VIDEODEC_H
extern "C"{
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libavutil/avutil.h"
#include "libavutil/mem.h"
#include "libavutil/fifo.h"
#include "libswscale/swscale.h"
}
#include <QObject>
#include <QImage>
#include <QThread>
#include <QDebug>
typedef quint8 uint8_t;
class VideoDec : public QObject
{
Q_OBJECT
public:
explicit VideoDec(QObject *parent = 0);
int videoindex;
AVFormatContext *pFormatCtx;
AVCodecContext *pCodecCtx;
AVCodec *pCodec;
AVPacket *packet;
AVFrame *pFrame,*pFrameRGB;
QString FileName;
signals:
void SendImage(QImage img);
public slots:
void init();
void play();
void setFileName(QString name);
};
#endif // VIDEODEC_H
videodec.cpp
#include "videodec.h"VideoDec::VideoDec(QObject *parent) : QObject(parent){}void VideoDec::init(){avcodec_register_all();
av_register_all();
pFormatCtx = avformat_alloc_context();if(avformat_open_input(&pFormatCtx, FileName.toLatin1().constData(), NULL, NULL) != 0){
qDebug() << "OpenFail";}
if(avformat_find_stream_info(pFormatCtx, NULL) < 0){
qDebug() << "FindFail";}
videoindex = -1;for(int i = 0; pFormatCtx->nb_streams; i++){
if(pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO){
videoindex = i;break;}
}
if(videoindex == -1){
qDebug() << "Din't find video stream";}
pCodecCtx = pFormatCtx->streams[videoindex]->codec;pCodec = avcodec_find_decoder(pCodecCtx->codec_id);if(pCodec == NULL){
qDebug() << "codec not find";}
if(avcodec_open2(pCodecCtx, pCodec, NULL) < 0){
qDebug() << "can't open codec";}
pFrame = avcodec_alloc_frame();pFrameRGB = avcodec_alloc_frame();play();
}void VideoDec::play(){int got_picture;
int size = pCodecCtx->width*pCodecCtx->height;packet=(AVPacket *)malloc(sizeof(AVPacket));av_new_packet(packet, size);
uint8_t *buffer;buffer = new uint8_t[avpicture_get_size(PIX_FMT_RGB32, pCodecCtx->width, pCodecCtx->height)];avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_RGB32, pCodecCtx->width, pCodecCtx->height);while(av_read_frame(pFormatCtx,packet) >= 0){
if(packet->stream_index == videoindex){
int rec = avcodec_decode_video2(pCodecCtx, pFrame, &got_picture, packet);if(rec > 0){
SwsContext *convertCtx = sws_getContext(pCodecCtx->width,pCodecCtx->height,pCodecCtx->pix_fmt,pCodecCtx->width,pCodecCtx->height,PIX_FMT_RGB32,SWS_BICUBIC,NULL, NULL, NULL);sws_scale(convertCtx, (const uint8_t* const*)pFrame->data, pFrame->linesize,0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);QImage Img((uchar *)pFrameRGB->data[0], pCodecCtx->width, pCodecCtx->height, QImage::Format_RGB32);emit SendImage(Img);}
}
av_free_packet(packet);QThread::msleep(4);}
}void VideoDec::setFileName(QString name){FileName = name;}