first commit

This commit is contained in:
2026-02-21 17:11:31 +09:00
commit 18b4338361
4001 changed files with 365464 additions and 0 deletions

View File

@@ -0,0 +1,275 @@
/******************************************************************************
QtAV: Multimedia framework based on Qt and FFmpeg
Copyright (C) 2012-2016 Wang Bin <wbsecg1@gmail.com>
* This file is part of QtAV (from 2014)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
******************************************************************************/
#ifndef QTAV_SUBTITLE_H
#define QTAV_SUBTITLE_H
#include "SubImage.h>
#include <QtCore/QObject>
#include <QtCore/QStringList>
#include <QtCore/QUrl>
#include <QtGui/QImage>
/*
* to avoid read error, subtitle size > 10*1024*1024 will be ignored.
*/
namespace FAV {
#if !(DO_NOT_USE_SUBTITLE)
class Q_AV_EXPORT SubtitleFrame
{
public:
SubtitleFrame() :
begin(0)
, end(0)
{}
// valied: begin < end
bool isValid() const { return begin < end;}
operator bool() const { return isValid();}
bool operator !() const { return !isValid();}
inline bool operator <(const SubtitleFrame& f) const { return end < f.end;}
inline bool operator <(qreal t) const { return end < t;}
qreal begin;
qreal end;
QString text; //plain text. always valid
};
class Q_AV_EXPORT Subtitle : public QObject
{
Q_OBJECT
Q_PROPERTY(QByteArray codec READ codec WRITE setCodec NOTIFY codecChanged)
// QList<SubtitleProcessorId>
Q_PROPERTY(QStringList engines READ engines WRITE setEngines NOTIFY enginesChanged)
Q_PROPERTY(QString engine READ engine NOTIFY engineChanged)
Q_PROPERTY(bool fuzzyMatch READ fuzzyMatch WRITE setFuzzyMatch NOTIFY fuzzyMatchChanged)
Q_PROPERTY(QByteArray rawData READ rawData WRITE setRawData NOTIFY rawDataChanged)
Q_PROPERTY(QString fileName READ fileName WRITE setFileName NOTIFY fileNameChanged)
Q_PROPERTY(QStringList dirs READ dirs WRITE setDirs NOTIFY dirsChanged)
Q_PROPERTY(QStringList suffixes READ suffixes WRITE setSuffixes NOTIFY suffixesChanged)
Q_PROPERTY(QStringList supportedSuffixes READ supportedSuffixes NOTIFY supportedSuffixesChanged)
Q_PROPERTY(qreal timestamp READ timestamp WRITE setTimestamp)
Q_PROPERTY(qreal delay READ delay WRITE setDelay NOTIFY delayChanged)
Q_PROPERTY(QString text READ getText)
Q_PROPERTY(bool loaded READ isLoaded)
Q_PROPERTY(bool canRender READ canRender NOTIFY canRenderChanged)
// font properties for libass engine
Q_PROPERTY(QString fontFile READ fontFile WRITE setFontFile NOTIFY fontFileChanged)
Q_PROPERTY(QString fontsDir READ fontsDir WRITE setFontsDir NOTIFY fontsDirChanged)
Q_PROPERTY(bool fontFileForced READ isFontFileForced WRITE setFontFileForced NOTIFY fontFileForcedChanged)
public:
explicit Subtitle(QObject *parent = 0);
virtual ~Subtitle();
/*!
* \brief setCodec
* set subtitle encoding that supported by QTextCodec. You have to call load() to manually reload the subtitle with given codec
* \param value codec name. see QTextCodec.availableCodecs(). Empty value means using the default codec in QTextCodec
* If linked with libchardet(https://github.com/cnangel/libchardet) or can dynamically load it,
* set value of "AutoDetect" to detect the charset of subtitle
*/
void setCodec(const QByteArray& value);
QByteArray codec() const;
/*!
* \brief isValid
* indicate whether the subtitle can be found and processed
* \return
*/
bool isLoaded() const;
/*!
* \brief setEngines
* Set subtitle processor engine names, in priority order. When loading a subtitle, use the engines
* one by one until a usable engine is found.
* \param value
*/
void setEngines(const QStringList& value);
QStringList engines() const;
/*!
* \brief engine
* \return The engine in use for current subtitle
*/
QString engine() const;
void setFuzzyMatch(bool value);
bool fuzzyMatch() const;
void setRawData(const QByteArray& data);
QByteArray rawData() const;
/*!
* \brief setFileName
* the given name will be in the 1st place to try to open(if using fuzzy match). then files in suffixes() order
* or in processor's supported suffixes order
* \param name
*/
void setFileName(const QString& name);
QString fileName() const;
/*!
* \brief setDirs
* Set subtitle search directories. Video's dir will always be added.
*/
void setDirs(const QStringList& value);
QStringList dirs() const;
/*!
* \brief supportedFormats
* the suffix names supported by all engines. for example ["ass", "ssa"]
* \return
*/
QStringList supportedSuffixes() const;
/*!
* \brief setSuffixes
* default is using SubtitleProcessor. Empty equals default value. But suffixes() will return empty.
*/
void setSuffixes(const QStringList& value);
QStringList suffixes() const;
qreal timestamp() const;
/*!
* \brief delay
* unit: second
* The subtitle from getText() and getImage() is at the time: timestamp() + delay()
* \return
*/
qreal delay() const;
void setDelay(qreal value);
/*!
* \brief canRender
* wether current processor supports rendering. Check before getImage()
* \return
*/
bool canRender() const;
// call setTimestamp before getText/Image
//plain text. separated by '\n' if more more than 1 text rects found
QString getText() const;
/*!
* \brief getImage
* Get a subtitle image with given (video) frame size. The result image size usually smaller than
* given frame size because subtitle are lines of text. The boundingRect indicates the actual
* image position and size relative to given size.
* The result image format is QImage::Format_ARGB32
* \return empty image if no image, or subtitle processor does not support renderering
*/
QImage getImage(int width, int height, QRect* boundingRect = 0);
SubImageSet getSubImages(int width, int height, QRect* boundingRect = 0);
// used for embedded subtitles.
/*!
* \brief processHeader
* Always called if switch to a new internal subtitle stream. But header data can be empty
* Used by libass to set style etc.
*/
bool processHeader(const QByteArray &codec, const QByteArray& data);
// ffmpeg decodes subtitle lines and call processLine. if AVPacket contains plain text, no decoding is ok
bool processLine(const QByteArray& data, qreal pts = -1, qreal duration = 0);
QString fontFile() const;
void setFontFile(const QString& value);
/*!
* \brief fontsDir
* Not tested for dwrite provider. FontConfig can work.
*/
QString fontsDir() const;
void setFontsDir(const QString& value);
bool isFontFileForced() const;
void setFontFileForced(bool value);
public Q_SLOTS:
/*!
* \brief start
* start to process the whole subtitle content in a thread
*/
void load();
void loadAsync();
void setTimestamp(qreal t);
Q_SIGNALS:
// TODO: also add to AVPlayer?
/// empty path if load from raw data
void loaded(const QString& path = QString());
void canRenderChanged();
void codecChanged();
void enginesChanged();
void fuzzyMatchChanged();
/*!
* \brief contentChanged
* emitted when text content changed.
*/
void contentChanged();
void rawDataChanged();
void fileNameChanged();
void dirsChanged();
void suffixesChanged();
void supportedSuffixesChanged();
void engineChanged();
void delayChanged();
void fontFileChanged();
void fontsDirChanged();
void fontFileForcedChanged();
private:
void checkCapability();
class Private;
Private *priv;
};
// internal use
class Q_AV_EXPORT SubtitleAPIProxy {
public:
SubtitleAPIProxy(QObject* obj);
void setSubtitle(Subtitle *sub);
// API from Subtitle
/*!
* \brief setCodec
* set subtitle encoding that supported by QTextCodec. subtitle will be reloaded
* \param value codec name. see QTextCodec.availableCodecs(). Empty value means using the default codec in QTextCodec
*/
void setCodec(const QByteArray& value);
QByteArray codec() const;
bool isLoaded() const;
void setEngines(const QStringList& value);
QStringList engines() const;
QString engine() const;
void setFuzzyMatch(bool value);
bool fuzzyMatch() const;
//always use exact file path by setFile(). file name is used internally
//void setFileName(const QString& name);
//QString fileName() const;
void setDirs(const QStringList& value);
QStringList dirs() const;
QStringList supportedSuffixes() const;
void setSuffixes(const QStringList& value);
QStringList suffixes() const;
bool canRender() const; // TODO: rename to capability()
qreal delay() const;
void setDelay(qreal value);
QString fontFile() const;
void setFontFile(const QString& value);
QString fontsDir() const;
void setFontsDir(const QString& value);
bool isFontFileForced() const;
void setFontFileForced(bool value);
// API from PlayerSubtitle
/*
void setFile(const QString& file);
QString file() const;
void setAutoLoad(bool value);
bool autoLoad() const;
*/
private:
QObject *m_obj;
Subtitle *m_s;
};
#endif // #if !(DO_NOT_USE_SUBTITLE)
} //namespace FAV
#endif // QTAV_SUBTITLE_H