FFmpeg入門(mén):概述與編譯

1喳坠、概述

與FFmpeg初識(shí)杈曲,大約是在六年前丈钙。那時(shí)公司要求做這么一個(gè)功能:運(yùn)營(yíng)編輯人員通過(guò)管理后臺(tái)上傳本地視頻文件或粘貼其他視頻網(wǎng)站的詳情頁(yè)地址非驮,獲取到視頻后,通過(guò)FFmpeg來(lái)轉(zhuǎn)碼為各種清晰度的視頻雏赦。那時(shí)剛畢業(yè)不久劫笙,只略懂PHP和JAVA芙扎,音視頻的知識(shí)更是一窮二白,只能通過(guò)JAVA調(diào)用系統(tǒng)命令行的方式使用FFmpeg填大,最終因?yàn)樾阅艿葐?wèn)題戒洼,項(xiàng)目流產(chǎn)了。再次相遇是兩年前允华,為提升ExoPlayer播放器的兼容性圈浇,為其添加視頻軟解功能。這次打開(kāi)FFmpeg的姿勢(shì)稍微帥一點(diǎn)靴寂,會(huì)使用FFmpeg API來(lái)做轉(zhuǎn)碼磷蜀。恍恍惚惚這么多年榨汤,一直都是FFmpeg的看客蠕搜,只在門(mén)口晃悠。

近來(lái)想稍微系統(tǒng)地學(xué)習(xí)一番F(xiàn)Fmpeg收壕,發(fā)現(xiàn)國(guó)內(nèi)關(guān)于FFmpeg的相關(guān)資料甚少妓灌。可參考的有:

  • 官方文檔:這里能了解到最新FFmpeg動(dòng)態(tài)
  • 雷神的博客:相信國(guó)內(nèi)大多數(shù)音視頻開(kāi)發(fā)者或多或少看過(guò)他的博文蜜宪,運(yùn)行過(guò)他的代碼虫埂。雷神已故,甚是可惜圃验。FFmpeg迭代很快掉伏,其中不少API使用已經(jīng)過(guò)時(shí),希望有更多的人延續(xù)雷神的分享精神澳窑。
  • 《FFmpeg從入門(mén)到精通》:本書(shū)側(cè)重于命令行的使用斧散,API甚少。作者應(yīng)該也是大神摊聋,只是過(guò)分惜墨鸡捐,導(dǎo)致文章內(nèi)容平鋪。

沒(méi)有經(jīng)過(guò)嚴(yán)格正確性驗(yàn)證的代碼或文章麻裁,都是耍流氓箍镜。我要開(kāi)始耍流氓了:

FFmpeg:A complete, cross-platform solution to record, convert and stream audio and video。稍微展開(kāi)就是:

  • 它是功能完備的煎源,性能優(yōu)越的色迂,支持跨平臺(tái)的音視頻處理框架。
  • record:音視頻錄制手销,更多地指將音視頻保存到本地文件
  • convert:轉(zhuǎn)換歇僧,包括多媒體文件格式轉(zhuǎn)換,音視頻編碼轉(zhuǎn)換锋拖,視頻縮放和色彩格式轉(zhuǎn)換诈悍,音頻處理等
  • stream:流化音視頻埂淮,更多指協(xié)議層的文件流,多媒體流等

下面是FFmpeg框架的分層模型:

FFmpeg分層模型
  • 協(xié)議層:該層處理流媒體協(xié)議的數(shù)據(jù)解析與封裝写隶,包括http,rtmp讲仰,rtsp慕趴,file等

  • 容器層:該層處理多媒體容器的解析和封裝,包括mp4鄙陡,flv冕房,mkv等

  • 編解碼層:該層負(fù)責(zé)音視頻編解碼,包括h264趁矾,h265耙册,mp3,aac等

  • 原始數(shù)據(jù)層:該層負(fù)責(zé)原始音視頻數(shù)據(jù)的處理毫捣,如視頻像素格式轉(zhuǎn)換详拙,縮放,裁剪蔓同,過(guò)濾饶辙,音頻重采樣,過(guò)濾等斑粱,處理對(duì)象是pcm弃揽,yuv,rgb等原始數(shù)據(jù)则北。

  • 設(shè)備層:負(fù)責(zé)音視頻播放及采集

看到這個(gè)是否聯(lián)想到 TCP/IP協(xié)議族的網(wǎng)絡(luò)分層模型矿微,從頂?shù)降追謩e是應(yīng)用層,傳輸層尚揣,網(wǎng)絡(luò)層涌矢,鏈路層,物理層惑艇。但兩者的設(shè)計(jì)有個(gè)很大的不同點(diǎn)蒿辙。網(wǎng)絡(luò)分層模型中,普通應(yīng)用開(kāi)發(fā)者只能在應(yīng)用層做文章滨巴;而FFmpeg分層模型相對(duì)自由靈活思灌,每層都提供了相對(duì)解耦的類庫(kù):

  • livavformat 作用于協(xié)議層和容器層,依賴于libavcodec恭取。
  • libavcodec 作用于編解碼層泰偿。
  • ibswscale,libswresample蜈垮,libavfilter作用于原始數(shù)據(jù)層耗跛。
  • libavdevice 作用于設(shè)備層裕照。
  • livavutil 是基礎(chǔ)公共模塊,上面各個(gè)類庫(kù)都會(huì)依賴于它调塌。

每個(gè)模塊的詳細(xì)說(shuō)明晋南,可查看官方文檔的 Libraries Documentation ,其中的常用的模塊是livavutil羔砾,libavcodec及l(fā)ibavformat负间。常規(guī)的多媒體開(kāi)發(fā)(不一定基于FFmpeg)都能映射到上面的FFmpeg分層模型中:如

  • 單看左邊,一路下來(lái)就是播放器的實(shí)現(xiàn)流程姜凄。
  • 單看右邊政溃,一路上去就是直播主播端的推流流程。
  • 若是不涉及改變編碼的文件格式轉(zhuǎn)換态秧,只在容器層就可實(shí)現(xiàn)董虱。
  • 若只想給已有的播放器,添加更多的解碼格式申鱼,只需使用到其中的編解碼層愤诱。

2、編譯

使用FFmpeg API的方式開(kāi)發(fā)润讥,編譯源碼是必然的转锈。首先從官網(wǎng)下載最新的穩(wěn)定版本(當(dāng)前是4.1),切記不要使用主干的最新代碼楚殿。原因有二:其一撮慨,主干代碼經(jīng)常更新,有不穩(wěn)定的可能脆粥,其二砌溺,使用固定版本,方便交流和定位問(wèn)題变隔。

FFmpeg編譯是我們首先需要面對(duì)的難題规伐,基本分為下面幾種情況:

  1. 通過(guò)編譯FFmpeg源碼的方式,安裝FFmpeg匣缘。
  2. 將FFmpeg移植到移動(dòng)平臺(tái)(Android和iOS)的交叉編譯猖闪。
  3. 將第三方類庫(kù)集成到FFmpeg,如集成x264肌厨,fdk-aac培慌。
  4. 本機(jī)編譯相關(guān)類庫(kù),及在本機(jī)環(huán)境使用FFmpeg API柑爸。

經(jīng)常能看到描述FFmpeg編譯的文章吵护,其下會(huì)有不少讀者抱怨,我完全按你的編譯配置及編譯腳本執(zhí)行,就是編譯失敗馅而,或者執(zhí)行失敗祥诽。喂蝦米!大體原因不外:

  • 編譯環(huán)境是否匹配瓮恭,包括操作系統(tǒng)雄坪,預(yù)安裝的編譯工具及特定平臺(tái)的編譯配置⊥捅模可參考官方編譯說(shuō)明诸衔。
  • FFmpeg版本是否一致。不同版本支持的配置項(xiàng)也有可能不一樣颇玷。
  • 需求是否一樣。FFmpeg是支持裁剪編譯的就缆。作者的編譯選項(xiàng)可能未包含你的需要的功能帖渠。

接下來(lái),來(lái)看一個(gè)我在mac平臺(tái)上編譯FFmpeg 4.1的腳本竭宰,主要用于在mac上調(diào)試運(yùn)行FFmpeg的開(kāi)發(fā)示例空郊。

COMMON_OPTIONS=" \
    --disable-doc \
    --disable-programs \
    --disable-everything \
    --disable-avdevice \
    --disable-postproc \
    --disable-avfilter \
    --disable-symver \
    --disable-avresample \
    --disable-audiotoolbox \
    --disable-videotoolbox \
    --disable-appkit \
    --disable-bzlib \
    --disable-iconv \
    --disable-securetransport \
    --disable-avfoundation \
    --disable-coreimage \
    --disable-sdl2 \
    --disable-zlib \
    --enable-decoder=h264 \
    --enable-decoder=aac \
    --enable-demuxer=mov \
    --enable-demuxer=flv \
    --enable-demuxer=rtsp \
    --enable-demuxer=mp3 \
    --enable-demuxer=h264 \
    --enable-demuxer=aac \
    --enable-muxer=mp4 \
    --enable-muxer=flv \
    --enable-muxer=h264 \
    --enable-muxer=adts \
    --enable-muxer=mp3 \
    --enable-protocol=rtmp \
    --enable-protocol=file \
    --enable-bsf=aac_adtstoasc \
    --enable-bsf=h264_mp4toannexb \
    --enable-bsf=hevc_mp4toannexb \
    " && \
./configure \
    --prefix='out' \
    ${COMMON_OPTIONS} \
    && \
make -j4 && make install && make clean

將其放置于FFmpeg源碼根目錄下(比如命名為build_pc.sh)。執(zhí)行如下終端命令:

chmod a+x ./build_pc.sh //使build_pc.sh為可執(zhí)行文件
./build_pc.sh //執(zhí)行構(gòu)建腳本

稍等片刻切揭,順利的話狞甚,便可在源碼根目錄下看到輸出文件out,其下包括頭文件目錄include廓旬,類庫(kù)文件目錄lib及示例文件目錄share哼审。仔細(xì)觀察,可發(fā)現(xiàn)其中也就四條命令:

編譯流程
  • configure 編譯裁剪配置
  • make 執(zhí)行編譯
  • make install 執(zhí)行安裝孕豹,就是將相關(guān)編譯好的程序涩盾,類庫(kù)以及頭文件示例代碼拷貝到—prefix 指定的目錄(上例為out目錄)
  • make clean 清理編譯過(guò)程產(chǎn)生的臨時(shí)文件

FFmpeg是個(gè)龐大的類庫(kù),最好根據(jù)我們的需求励背,進(jìn)行編譯選項(xiàng)配置春霍。執(zhí)行如下命令,可查看到所有配置項(xiàng)叶眉。

./configure --help

其中常用的配置如下:

Help options:
  --list-decoders          show all available decoders
  --list-encoders          show all available encoders
  --list-hwaccels          show all available hardware accelerators
  --list-demuxers          show all available demuxers
  --list-muxers            show all available muxers
  --list-parsers           show all available parsers
  --list-protocols         show all available protocols
  --list-bsfs              show all available bitstream filters
  --list-indevs            show all available input devices
  --list-outdevs           show all available output devices
  --list-filters           show all available filters

Standard options:
  --prefix=PREFIX          install in PREFIX [/usr/local]

Configuration options:
  --disable-static         do not build static libraries [no]
  --enable-shared          build shared libraries [no]

Program options:
  --disable-programs       do not build command line programs
  --disable-ffmpeg         disable ffmpeg build
  --disable-ffplay         disable ffplay build
  --disable-ffprobe        disable ffprobe build

Documentation options:
  --disable-doc            do not build documentation

Component options:
  --disable-avdevice       disable libavdevice build
  --disable-avcodec        disable libavcodec build
  --disable-avformat       disable libavformat build
  --disable-swresample     disable libswresample build
  --disable-swscale        disable libswscale build
  --disable-postproc       disable libpostproc build
  --disable-avfilter       disable libavfilter build
  --enable-avresample      enable libavresample build (deprecated) [no]

Individual component options:
  --disable-everything     disable all components listed below
  --enable-encoder=NAME    enable encoder NAME
  --enable-decoder=NAME    enable decoder NAME
  --enable-muxer=NAME      enable muxer NAME
  --enable-demuxer=NAME    enable demuxer NAME
  --enable-parser=NAME     enable parser NAME
  --enable-bsf=NAME        enable bitstream filter NAME
  --enable-protocol=NAME   enable protocol NAME
  --enable-filter=NAME     enable filter NAME

External library support:
  --enable-libfdk-aac      enable AAC de/encoding via libfdk-aac [no]
  --enable-libmp3lame      enable MP3 encoding via libmp3lame [no]
  --enable-libx264         enable H.264 encoding via x264 [no]
  --enable-libx265         enable HEVC encoding via x265 [no]

Toolchain options:
  --arch=ARCH              select architecture []
  --cpu=CPU                select the minimum required CPU (affects
                           instruction selection, may crash on older CPUs)
  --cross-prefix=PREFIX    use PREFIX for compilation tools []
  --sysroot=PATH           root of cross-build tree
  --sysinclude=PATH        location of cross-build system headers
  --target-os=OS           compiler targets OS []

Optimization options (experts only):
  --disable-asm            disable all assembly optimizations
  --disable-neon           disable NEON optimizations

通常使用“禁大開(kāi)小”的配置策略址儒。如下是常見(jiàn)的禁止配置:

--disable-doc // 禁止輸出文檔
--disable-programs // 禁止編譯執(zhí)行程序 ffmpeg ffprobe ffplay
--disable-everything // 禁止所有的encoder,decoder衅疙,muxer莲趣,demuxer,parser炼蛤,bsf妖爷,protocol及filter
--disable-avdevice // 禁止相關(guān)模塊 這些模塊在上面的分層模型提及
--disable-postproc
--disable-avfilter

根據(jù)實(shí)際的需求,再開(kāi)啟相關(guān)配置:

--enable-decoder=h264
--enable-decoder=aac
--enable-demuxer=mov
--enable-demuxer=flv
--enable-protocol=file

默認(rèn)是只編譯靜態(tài)庫(kù),可通過(guò) --enable-shared 開(kāi)啟動(dòng)態(tài)庫(kù)的編譯絮识。默認(rèn)會(huì)將編譯輸出到 /usr/local目錄绿聘,可配置--prefix=輸出目錄 來(lái)修改。Toolchain options通用用于交叉編譯次舌,可參考ExoPlayer集成FFmpeg熄攘。

在執(zhí)行編譯腳本時(shí),最開(kāi)始的輸出日志是最關(guān)鍵的彼念,可以看出是否符合你的預(yù)期:

install prefix            out
source path               .
C compiler                gcc
C library                 
ARCH                      x86 (generic)
...
static                    yes
shared                    no
...

External libraries:

External libraries providing hardware acceleration:

Libraries:
avcodec           avformat          avutil            swresample        swscale

Programs:

Enabled decoders:
aac           h264

Enabled encoders:

Enabled hwaccels:

Enabled parsers:
mpegaudio

Enabled demuxers:
aac           flv               mov               mpegts            rtsp
asf           h264              mp3               rm

Enabled muxers:
adts              flv               h264              mov           mp3           mp4

Enabled protocols:
file              http              rtmp              rtp           tcp           udp

Enabled filters:

Enabled bsfs:
aac_adtstoasc         h264_mp4toannexb      hevc_mp4toannexb          null

Enabled indevs:

Enabled outdevs:

以上就是FFmpeg編譯的基本脈絡(luò)挪圾。若你能一次編譯成功,且能在項(xiàng)目中成功運(yùn)行的逐沙,那你可以去買彩票了哲思。通常或多或少有平臺(tái)相關(guān)的問(wèn)題吩案,先查找官方編譯說(shuō)明棚赔,未果再google一下。

3徘郭、小試牛刀

了解了FFmpeg的概貌及編譯后靠益,接下來(lái)就可使用相關(guān)的API。官方API文檔残揉,及官方示例是學(xué)習(xí)FFmpeg API的最佳資料胧后。以此為基點(diǎn),慢慢張開(kāi)抱环,若有疑問(wèn)壳快,可查看源碼,亦可從網(wǎng)上需求答案镇草∩髁辏可用下面示例驗(yàn)證我們編譯的類庫(kù)包括哪些組件:

// 輸出版本信息加酵,編譯配置等
std::cout << "version:" << av_version_info() << " avformat:" << avformat_version() << " avcodec:"
    << avcodec_version() << " avutil:" << avutil_version() << std::endl;
std::cout << "license:" << avformat_license() << std::endl;
std::cout << "configuration:" << avformat_configuration() << std::endl;

void *opaque = NULL;
// 獲取所有協(xié)議
std::cout << "=== input protocols ===" << std::endl;
const char *protocol = avio_enum_protocols(&opaque, 0);
while (protocol!=NULL){
    std::cout << protocol << std::endl;
    protocol = avio_enum_protocols(&opaque, 0);
}

std::cout << "=== output protocols ===" << std::endl;
protocol = avio_enum_protocols(&opaque, 1);
while (protocol!=NULL){
    std::cout << protocol << std::endl;
    protocol = avio_enum_protocols(&opaque, 1);
}

// 獲取所有的解封裝器
std::cout << "=== demuxer ===" << std::endl;
const AVInputFormat *inputFormat = av_demuxer_iterate(&opaque);
while (inputFormat != NULL) {
    std::cout << inputFormat->name << std::endl;
    inputFormat = av_demuxer_iterate(&opaque);
}

// 獲取所有封裝器
std::cout << "=== muxer ===" << std::endl;
opaque = NULL;
const AVOutputFormat *outputFormat = av_muxer_iterate(&opaque);
while (outputFormat != NULL) {
    std::cout << outputFormat->name << std::endl;
    outputFormat = av_muxer_iterate(&opaque);
}

// 獲取所有編碼器
std::cout << "=== encoder ===" << std::endl;
opaque = NULL;
const AVCodec *avCodec = av_codec_iterate(&opaque);
while (avCodec != NULL) {
    if(av_codec_is_encoder(avCodec)){
        std::cout << avCodec->name << std::endl;
    }
    avCodec = av_codec_iterate(&opaque);
}

// 獲取所有編碼器
std::cout << "=== decoder ===" << std::endl;
opaque = NULL;
avCodec = av_codec_iterate(&opaque);
while (avCodec != NULL) {
    if(av_codec_is_decoder(avCodec)){
        std::cout << avCodec->name << std::endl;
    }
    avCodec = av_codec_iterate(&opaque);
}

// 獲取所有bsf
std::cout << "=== bsf ===" << std::endl;
opaque = NULL;
const AVBitStreamFilter *bsf = av_bsf_iterate(&opaque);
while (bsf != NULL) {
    std::cout << bsf->name << std::endl;
    bsf = av_bsf_iterate(&opaque);
}

FFmpeg使用C語(yǔ)言編寫(xiě),其API是一些核心函數(shù)和關(guān)鍵結(jié)構(gòu)體的集合。組織方式相對(duì)松散刽辙,新手容易迷路信柿。再細(xì)看精盅,發(fā)現(xiàn)其是基于對(duì)象(結(jié)構(gòu)體)及上下文的方式來(lái)貫穿多媒體處理的會(huì)話周期胳施。在官方示例中能發(fā)現(xiàn)各個(gè)應(yīng)用場(chǎng)景的使用基本套路。

后續(xù)文章以分享這些示例的學(xué)習(xí)筆記為主羽嫡,與君共勉本姥。。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末杭棵,一起剝皮案震驚了整個(gè)濱河市婚惫,隨后出現(xiàn)的幾起案子氛赐,更是在濱河造成了極大的恐慌,老刑警劉巖先舷,帶你破解...
    沈念sama閱讀 222,252評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件艰管,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡蒋川,警方通過(guò)查閱死者的電腦和手機(jī)牲芋,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,886評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)捺球,“玉大人缸浦,你說(shuō)我怎么就攤上這事〉” “怎么了裂逐?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,814評(píng)論 0 361
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)泣栈。 經(jīng)常有香客問(wèn)我絮姆,道長(zhǎng),這世上最難降的妖魔是什么秩霍? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,869評(píng)論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮蚁阳,結(jié)果婚禮上铃绒,老公的妹妹穿的比我還像新娘。我一直安慰自己螺捐,他們只是感情好颠悬,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,888評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著定血,像睡著了一般赔癌。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上澜沟,一...
    開(kāi)封第一講書(shū)人閱讀 52,475評(píng)論 1 312
  • 那天灾票,我揣著相機(jī)與錄音,去河邊找鬼茫虽。 笑死刊苍,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的濒析。 我是一名探鬼主播正什,決...
    沈念sama閱讀 41,010評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼号杏!你這毒婦竟也來(lái)了婴氮?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,924評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎主经,沒(méi)想到半個(gè)月后荣暮,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,469評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡旨怠,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,552評(píng)論 3 342
  • 正文 我和宋清朗相戀三年渠驼,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片鉴腻。...
    茶點(diǎn)故事閱讀 40,680評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡迷扇,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出爽哎,到底是詐尸還是另有隱情蜓席,我是刑警寧澤,帶...
    沈念sama閱讀 36,362評(píng)論 5 351
  • 正文 年R本政府宣布课锌,位于F島的核電站厨内,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏渺贤。R本人自食惡果不足惜雏胃,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,037評(píng)論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望志鞍。 院中可真熱鬧瞭亮,春花似錦、人聲如沸固棚。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,519評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)此洲。三九已至厂汗,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間呜师,已是汗流浹背娶桦。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,621評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留汁汗,地道東北人趟紊。 一個(gè)月前我還...
    沈念sama閱讀 49,099評(píng)論 3 378
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像碰酝,于是被迫代替她去往敵國(guó)和親霎匈。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,691評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容

  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫(kù)送爸、插件铛嘱、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,123評(píng)論 4 61
  • 不少家長(zhǎng)都感到為了孩子付出很多:要花錢給孩子買這買那墨吓,要花時(shí)間接送孩子上學(xué)放學(xué)球匕、上輔導(dǎo)班等等。父母在教育孩子方面帖烘,...
    子態(tài)閱讀 346評(píng)論 0 0
  • 在當(dāng)下吃雞如此大火的情況下 男女逛街什么的早已成為過(guò)去 而男女吃雞亮曹,反倒成為了約會(huì)首選 某大神就用紅藍(lán)圓珠筆漫畫(huà)的...
    Doris_KK8閱讀 369評(píng)論 0 0
  • 雨打嬌荷心難平, 又見(jiàn)流水載落紅秘症。 只道此雨世所罕照卦, 未曾放任雨中游。 tulipjia去年同期作品乡摹,那是一場(chǎng)罕見(jiàn)...
    tulipjia閱讀 195評(píng)論 0 6
  • 李揚(yáng)打了個(gè)呵欠役耕,抬手看了看表,然后打開(kāi)了攝像機(jī)聪廉。 “就這樣就可以了吧瞬痘?”他對(duì)著正坐在不遠(yuǎn)處的王猛山大聲說(shuō)道。 王猛...
    楚游塵閱讀 693評(píng)論 0 51