利用Olami SDK 實(shí)現(xiàn)語音控制計(jì)算器(iOS)

一鞍爱、簡(jiǎn)介:
Olami Calculator是一款在鍵盤輸入算式的普通計(jì)算器的基礎(chǔ)上踏兜,增加了支持語音控制輸入算式輸出結(jié)果的人工智能計(jì)算器军拟。此外還增加了多種動(dòng)畫效果幸乒,計(jì)算結(jié)果提示音功能胀葱,多元化主題換膚功能漠秋,以及保存計(jì)算公式,側(cè)滑欄查看收藏記錄等功能抵屿。網(wǎng)上也有許多語音計(jì)算器庆锦,但是打開看,只是添加了按鈕提示音等轧葛,并不能識(shí)別我們對(duì)著計(jì)算器說的內(nèi)容搂抒,而Olami Calculator可以實(shí)現(xiàn)不用手動(dòng)敲擊鍵盤,只需要把想知道結(jié)果的算式對(duì)著語音計(jì)算器說出來尿扯,例如三加四乘五乙墙、清空等凄贩,然后Olami會(huì)根據(jù)自己的一套語音識(shí)別系統(tǒng)幫我們準(zhǔn)確識(shí)別出來记焊。真正做到一款語音控制的計(jì)算器豫领。

二、界面直觀化展示

圖片描述
其中包括結(jié)果FMDB收藏辟宗、側(cè)滑欄爵赵、主題換膚、音量正余弦動(dòng)畫等多種動(dòng)畫泊脐、混合運(yùn)算算法等等空幻。

三、Olami SDK的配置
step 1:創(chuàng)建工程與導(dǎo)入sdk Olami SDK下載地址:https://github.com/olami-developers/olami-sdk-ios.git 下載下來之后我們可以看到sdk-libs文件夾:

容客,把libOlamiRecognizer.a靜態(tài)庫文件和OlamiRecognize.h對(duì)外提供接口文件拖入到我們的工程中秕铛。配置工程:

step 2 : 創(chuàng)建Olami應(yīng)用 點(diǎn)擊https://cn.olami.ai/open/website/home/home_show注冊(cè)創(chuàng)建個(gè)人賬號(hào)并登陸则剃。進(jìn)入后創(chuàng)建新應(yīng)用,建好之后進(jìn)入應(yīng)用管理可以看到下面界面

點(diǎn)擊查看key:

step 3:可直接導(dǎo)入的語音模塊 點(diǎn)擊配置模塊選擇你需要的語音模塊如捅,目前有天氣,二十四點(diǎn)调煎,新聞镜遣,聽書,數(shù)學(xué)等50~多個(gè)模塊士袄,

悲关,供大家選擇的還是很多的。也可以點(diǎn)擊“進(jìn)入NLI系統(tǒng)”娄柳,再點(diǎn)擊導(dǎo)入寓辱,可以看到如下界面,這里也是已經(jīng)有的模塊有需要的直接導(dǎo)入:

step 4:自定制語音模塊 olami平臺(tái)會(huì)為廣大開發(fā)者提供一些已經(jīng)寫好了的語法模塊赤拒,如果提供給大家的模塊不能滿足當(dāng)下解析錄入語音的需求秫筏,那么不要慌,下面就是教大家如何定制屬于自己的模塊挎挖。 首先.登錄这敬,進(jìn)入我的應(yīng)用(沒有應(yīng)用的話記得創(chuàng)建新應(yīng)用哦),然后點(diǎn)擊“進(jìn)入NLI系統(tǒng)”蕉朵。下面是點(diǎn)擊之后的界面崔涂,可以看到右上角有導(dǎo)入和新增


如果沒有所需的模塊,那么就需要點(diǎn)擊”新增“始衅。我們做的是計(jì)算器那就給個(gè)名字冷蚂,輸入calculate,提交成功后可以看到我的模塊里面有了一個(gè)新模塊汛闸,:
點(diǎn)擊calculate后面的進(jìn)入模塊蝙茶。界面中有例句庫,grammar蛉拙,rule尸闸,slot,template模板孕锄。

現(xiàn)在做的計(jì)算器吮廉,那需要olami為我們識(shí)別出什么呢? 比如:9+8+7 就這個(gè)算式而言畸肆,我們對(duì)著蜜蜜說完宦芦,是希望把數(shù)字還有符號(hào)都給我們識(shí)別出來的。
分析:”9”轴脐、”+”调卑、”8”抡砂、”+”、”7”是我們需要系統(tǒng)幫我們識(shí)別并且返回給我們的變量恬涧,那就可以在slot設(shè)置5個(gè)變量注益,slot有五種類型(這里數(shù)字用float、符號(hào)用internal)溯捆,rule是一些臨時(shí)的中間表達(dá)式:[等于|結(jié)果是]丑搔,modifier傳遞預(yù)定義好的信息,不管是slot還是rule都是為grammar服務(wù)的提揍,要顯示句子要寫grammar啤月。 各舉一個(gè)例子: grammar:名稱:兩個(gè)數(shù)結(jié)果等于多少 內(nèi)容:[<再>][<數(shù)字一>][<符號(hào)一>][<數(shù)字二>][<結(jié)果是>|<等于幾>] slot:名稱:數(shù)字一 類型:float 最長:50 最短:1 rule:名稱:結(jié)果是 內(nèi)容:[的]結(jié)果[是|等于[多少|(zhì)幾]] (|:或 []:可以省略的)。 要更多的了解點(diǎn)擊這里查看OSL 語法描述語言 grammar的簡(jiǎn)介:https://cn.olami.ai/wiki/?mp=overview&content=quickstart.html劳跃。 一切就緒提交成功了之后谎仲,就可以測(cè)試了,測(cè)試無誤滿足需求刨仑,點(diǎn)擊“發(fā)布”就可以使用啦郑诺!
上圖:
1.新增grammar:

2.添加語料:寫出希望可以識(shí)別的一句grammar,測(cè)試并提交

3.最后測(cè)試無誤一定要點(diǎn)發(fā)布

4.完成配置 以上都完成了回到應(yīng)用管理贸人,我們就可以配置自己搭建的模塊了间景!

5.再測(cè)試 噔噔噔噔~可以使用了,變量都幫我們識(shí)別出來了艺智!



四倘要、代碼處實(shí)現(xiàn)
先來看下OlamiRecognizer.h為我提供了哪些接口

/
-(void)onResult:(NSData
)result;
/*
*取消本次會(huì)話
*/
-(void)onCancel;

/*
*識(shí)別失敗
*/
-(void)onError:(NSError *)error;

/*
*音量的大小 音頻強(qiáng)度范圍時(shí)0到100
*/
-(void)onUpdateVolume:(float) volume;

/***
*開始錄音
*/
-(void)onBeginningOfSpeech;

/**
*結(jié)束錄音

*/
-(void)onEndOfSpeech;
@end

typedef NS_ENUM(NSInteger, LanguageLocalization) {
LANGUAGE_SIMPLIFIED_CHINESE = 0, //簡(jiǎn)體中文
LANGUAGE_TRADITIONA_CHINESE = 1 //繁體中文
};
@interface OlamiRecognizer : NSObject
@property (nonatomic,weak) id<OlamiRecognizerDelegate> delegate;
@property (nonatomic, assign,readonly) BOOL isRecording;//是否正在錄音
-(void)start;//開始錄音
-(void)stop;//結(jié)束錄音,開始識(shí)別
-(void)cancel;//取消本次回話
/**
設(shè)置語系的選項(xiàng)十拣,目前只支持一種封拧,簡(jiǎn)體中文
/
-(void)setLocalization:(LanguageLocalization) location;
/

CUSID;//終端用戶標(biāo)識(shí)id,用來區(qū)分各個(gè)最終用戶 例如:手機(jī)的IMEI
appKey;//創(chuàng)建應(yīng)用的appkey
api;//要調(diào)用的API類型∝参剩現(xiàn)有3種:語義(nli)和分詞(seg)和語音(asr)
appSecret;//加密的秘鑰泽西,由應(yīng)用管理自動(dòng)生成
/
-(void)setAuthorization:(NSString
)appKey api:(NSString
)api appSecret:(NSString
)appSecret cusid:(NSString
)CUSID;
-(void)setVADTimeoutFrontSIL:(unsigned int)value;//設(shè)置VAD前端點(diǎn)超時(shí)范圍 100010000(ms) 默認(rèn)3000
-(void)setVADTimeoutBackSIL:(unsigned int)value;//設(shè)置VAD后端點(diǎn)超時(shí)范圍 1000
10000(ms) 默認(rèn)2000
-(void)setInputType:(int) type;//設(shè)置是語音輸入還是文字輸入 0 為語音 1為文字輸入
-(void)setLatitudeAndLongitude:(double) latitude longitude:(double)longit;//設(shè)置地理位置,參數(shù)為經(jīng)緯度
-(void)sendText:(NSString
)text;//發(fā)送輸入的文字

項(xiàng)目中,首先 初始化Olami語音識(shí)別對(duì)象并設(shè)置代理

/**
*CUSID;//終端用戶標(biāo)識(shí)id缰趋,用來區(qū)分各個(gè)最終用戶 例如:手機(jī)的IMEI
*appKey;//創(chuàng)建應(yīng)用的appkey
*api;//要調(diào)用的API類型∨跎迹現(xiàn)有3種:語義(nli)和分詞(seg)和語音(asr)
*appSecret;//加密的秘鑰,由應(yīng)用管理自動(dòng)生成
*/

define AppKey @""http://查看自己的

define AppSecret @""

define macID @""

-(void)setupOLAMI{
_olamiRecognizer= [[OlamiRecognizer alloc] init];
_olamiRecognizer.delegate = self;//此處為OlamiRecognizerDelegate

[_olamiRecognizer setAuthorization:AppKey api:@"asr" appSecret:AppSecret cusid:macID];

//設(shè)置語言秘血,目前只支持中文
[_olamiRecognizer setLocalization:LANGUAGE_SIMPLIFIED_CHINESE];

}

識(shí)別音量

pragma mark--NLU delegate

  • (void)onUpdateVolume:(float)volume {
    if (_olamiRecognizer.isRecording) {
    _waveView.present = volume/100;
    }
    }

waveview: 根據(jù)sin函數(shù) y=Asin(ωx+φ)+b
//e.g.:1.
CGContextRef context = UIGraphicsGetCurrentContext();

CGMutablePathRef path = CGPathCreateMutable();

CGContextSetLineWidth(context, 3);
CGContextSetLineCap(context, kCGLineCapRound);
CGContextSetAllowsAntialiasing(context, true);
CGContextSetRGBStrokeColor(context, 124 / 255.0, 145 / 255.0, 155 / 255.0, 1.0);  
CGContextBeginPath(context);

float y= (1 - _present) * rect.size.height;

CGPathMoveToPoint(path, NULL, -10, y);
for(float x=0;x<=rect.size.width;x++){
    y=  sin( 3*x/rect.size.width * M_PI + moveX/rect.size.width *M_PI ) *maxA + _currentLinePointY;
    CGPathAddLineToPoint(path, nil, x, y);
}

CGContextAddPath(context, path);

CGContextDrawPath(context, kCGPathStroke);
CGPathRelease(path);

主要是看返回來的result
調(diào)用代理這個(gè)方法-(void)onResult:(NSData*)result; 其語義分析后的結(jié)果以一個(gè)json字符串的形式回調(diào)過來味抖,對(duì)這個(gè)字符串進(jìn)行解析,就可以獲得想要的變量灰粮。

pragma mark --返回結(jié)果

  • (void)onResult:(NSData *)result {
    NSError *error;
    __weak typeof(self) weakSelf = self;
    if (error) {
    NSLog(@"error is %@",error.localizedDescription);
    }else{
    NSDictionary *json = [NSJSONSerialization JSONObjectWithData:result
    options:NSJSONReadingMutableContainers
    error:&error];
    NSLog(@"json=%@",json);

      if ([json[@"status"] isEqualToString:@"ok"]) {
    
    
          NSDictionary *asr = [json[@"data"] objectForKey:@"asr"];
    
          //如果asr不為空仔涩,說明目前是語音輸入
          if (asr) {
              [weakSelf processASR:asr];
          }
    
    
          NSDictionary *nli = [[json[@"data"] objectForKey:@"nli"] objectAtIndex:0];
          NSDictionary *desc = [nli objectForKey:@"desc_obj"];
          int status = [[desc objectForKey:@"status"] intValue];
          if (status != 0) {// 0 說明狀態(tài)正常,非零為狀態(tài)不正常
              NSString *result  = [desc objectForKey:@"result"];
              dispatch_async(dispatch_get_main_queue(), ^{
                  _resultLabel.text = result;//輸出不正常提示
                  _resultLabel.font = [UIFont systemFontOfSize:20];
                  [_resultLabel startAnimation];
    
                  _showTextView.text = asr[@"result"];
                  AudioServicesPlaySystemSound (soundID);
              });
    
          }else{
              NSDictionary *semantic = [[nli objectForKey:@"semantic"]
                                        objectAtIndex:0];
              //對(duì)slot和算式的處理結(jié)果
              [weakSelf processSemantic:semantic asr:asr];
              //處理modifier
              NSArray *modifierArr = [semantic objectForKey:@"modifier"];
    
              [weakSelf processModifier:modifierArr result:desc[@"result"]];
          }
    
    
      }else{
          _showTextView.text = @"請(qǐng)說出要計(jì)算的公式";
      }
    

    }

}

pragma mark --處理ASR語音對(duì)話節(jié)點(diǎn)

  • (void)processASR:(NSDictionary*)asrDic {
    NSString *result = [asrDic objectForKey:@"result"];
    if (result.length == 0) { //如果結(jié)果為空,則彈出警告框
    [self showAlert:@"沒有接受到語音粘舟,請(qǐng)重新輸入!"];
    return;
    }else{
    dispatch_async(dispatch_get_main_queue(), ^{
    NSString *str = [result stringByReplacingOccurrencesOfString:@" " withString:@""];//去掉字符中間的空格
    NSLog(@"answer result = %@",str);
    });
    }
    }

//處理semantic節(jié)點(diǎn)返回的slot

  • (void)processSemantic:(NSDictionary*)semanticDic asr:(NSDictionary *)asr {
    NSMutableArray *sumArr = [NSMutableArray array];
    for (NSDictionary *dic in semanticDic[@"slots"]) {
    NSString *nameStr = dic[@"name"];
    //遍歷熔脂,然后把slot添加到數(shù)組里
    NSString *textStr = [[sumArr componentsJoinedByString:@","] stringByReplacingOccurrencesOfString:@"," withString:@""];
    NSLog(@"textstr=%@",textStr);

    if (![textStr isEqualToString:@""]) {
    _passString = [self replaceInputStrWithPassStr:textStr];

      if (asr) {
          _lastAnswer = _resultLabel.text;//語音記錄上一次記錄
      }else{
          _lastAnswer = @"";
      }
    
      //第一次運(yùn)算或者不再加
      if ([_lastAnswer isEqualToString:@"error"]||[_lastAnswer isEqualToString:@""]) {
          if (asr) {
              dispatch_async(dispatch_get_main_queue(), ^{
                  _showTextView.text = [[textStr stringByReplacingOccurrencesOfString:@"2√" withString:@"√"] stringByAppendingString:@"="];//計(jì)算公式
              });
              textStr = [_calcultor calculatingWithString:_passString andAnswerString:@"0"];
          }else{
              textStr = [_calcultor calculatingWithString:_passString andAnswerString:@"0"];
          }
    
    
      //有結(jié)果考慮再運(yùn)算的步驟
      }else{
    
          //有結(jié)果再運(yùn)算的情況
          UniChar c = [_passString characterAtIndex:0];
          if (c =='-'|| c == '+'||c == 'x'||c =='/')
          {
              dispatch_async(dispatch_get_main_queue(), ^{
                  _showTextView.text = [[_lastAnswer stringByAppendingString:[textStr stringByReplacingOccurrencesOfString:@"2√" withString:@"√"]] stringByAppendingString:@"="];//計(jì)算公式
              });
    
              textStr = [_calcultor calculatingWithString:[_lastAnswer stringByAppendingString:_passString] andAnswerString:@"0"];//
          }
          //有結(jié)果但是不想再運(yùn)算
          else{
              dispatch_async(dispatch_get_main_queue(), ^{
                  _showTextView.text = [[textStr stringByReplacingOccurrencesOfString:@"2√" withString:@"√"] stringByAppendingString:@"="];//計(jì)算公式
              });
              textStr = [_calcultor calculatingWithString:_passString andAnswerString:@"0"];
          }
    
      }
    
      dispatch_async(dispatch_get_main_queue(), ^{
              AudioServicesPlaySystemSound (soundID1);
    
              _resultLabel.font = [UIFont systemFontOfSize:50.0];
              _resultLabel.text = textStr;
      });
    
      [_resultLabel startAnimation];
    

    }
    }

后臺(tái)返回:語音內(nèi)容是顯示在asr字段里佩研,大家可能會(huì)有疑問后臺(tái)怎么識(shí)別的我們語音的內(nèi)容,這是由于我們之前在olami平臺(tái)創(chuàng)建新應(yīng)用后導(dǎo)入了一套識(shí)別相應(yīng)內(nèi)容的grammar霞揉,這樣olami的語義解析功能會(huì)為我們自動(dòng)識(shí)別出想要得到的變量內(nèi)容旬薯。

比如我說:3+6乘九等于幾?
對(duì)應(yīng)grammar語法:[<再>][<數(shù)字一>]<符號(hào)一><數(shù)字二><符號(hào)二><數(shù)字三>[<結(jié)果>|<等于>]
返回結(jié)果:

json={
data = {
asr = {
final = 1;
result = "\U4e09\U52a0\U516d\U4e58\U4e5d\U7b49\U4e8e\U51e0";
"speech_status" = 0;
status = 0;
};
nli = (
{
"desc_obj" = {
status = 0;
};
semantic = (
{
app = calculator;
customer = 59530feb84aea6f385319c65;
input = "\U4e09\U52a0\U516d\U4e58\U4e5d\U7b49\U4e8e\U51e0";
modifier = (
);
slots = (
{
name = number3;
"num_detail" = {
"recommend_value" = 9;
type = float;
};
value = "\U4e5d";
},
{
name = number1;
"num_detail" = {
"recommend_value" = 3;
type = float;
};
value = "\U4e09";
},
{
name = number2;
"num_detail" = {
"recommend_value" = 6;
type = float;
};
value = "\U516d";
},
{
name = symbol1;
value = "+";
},
{
name = symbol2;
value = x;
}
);
}
);
type = calculator;
}
);
};
status = ok;
}

再加三等于幾适秩?
對(duì)應(yīng)grammar:[<再>][<數(shù)字一>][<符號(hào)一>][<數(shù)字二>][<結(jié)果>|<等于>] 袍暴、
后臺(tái)返回json字段:

json={
data = {
asr = {
final = 1;
result = "\U518d\U52a0\U4e09\U7b49\U4e8e\U51e0";
"speech_status" = 0;
status = 0;
};
nli = (
{
"desc_obj" = {
status = 0;
};
semantic = (
{
app = calculator;
customer = 59530feb84aea6f385319c65;
input = "\U518d\U52a0\U4e09\U7b49\U4e8e\U51e0";
modifier = (
);
slots = (
{
name = again;
value = a;
},
{
name = number2;
"num_detail" = {
"recommend_value" = 3;
type = float;
};
value = "\U4e09";
},
{
name = symbol1;
value = "+";
}
);
}
);
type = calculator;
}
);
};
status = ok;
}

計(jì)算過程:涉及到算法數(shù)據(jù)結(jié)構(gòu)堆棧問題隶症,大概思路設(shè)置優(yōu)先級(jí),設(shè)置兩個(gè)棧岗宣,一個(gè)數(shù)據(jù)棧蚂会,一個(gè)運(yùn)算符棧,在運(yùn)算符棧底添加#方便處理耗式。獲取表達(dá)式第一個(gè)元素如果是數(shù)據(jù)添加到數(shù)據(jù)棧中胁住,元素如果是運(yùn)算符,那么每次都要跟運(yùn)算符棧定元素比較優(yōu)先級(jí)刊咳,如果取得的運(yùn)算符的優(yōu)先級(jí)大于棧頂元素優(yōu)先級(jí)時(shí)彪见,該運(yùn)算符直接進(jìn)棧,優(yōu)先級(jí)不大的話娱挨,就要取棧頂運(yùn)算符優(yōu)先運(yùn)算余指,最后碰到#停止。如果有記憶上一輪結(jié)果的話跷坝,結(jié)果需要放到數(shù)據(jù)棧棧進(jìn)行下一次處理

代碼下載地址:https://github.com/zhaoshihui/calculator_olami_ios.git

您喜歡的話還請(qǐng)多多支持酵镜,不明白可以留言也歡迎加qq、微信討論:121003626

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末柴钻,一起剝皮案震驚了整個(gè)濱河市淮韭,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌贴届,老刑警劉巖靠粪,帶你破解...
    沈念sama閱讀 218,640評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異毫蚓,居然都是意外死亡占键,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,254評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門绍些,熙熙樓的掌柜王于貴愁眉苦臉地迎上來捞慌,“玉大人,你說我怎么就攤上這事柬批⌒ピ瑁” “怎么了袖订?”我有些...
    開封第一講書人閱讀 165,011評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長嗅虏。 經(jīng)常有香客問我洛姑,道長,這世上最難降的妖魔是什么皮服? 我笑而不...
    開封第一講書人閱讀 58,755評(píng)論 1 294
  • 正文 為了忘掉前任楞艾,我火速辦了婚禮,結(jié)果婚禮上龄广,老公的妹妹穿的比我還像新娘硫眯。我一直安慰自己,他們只是感情好择同,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,774評(píng)論 6 392
  • 文/花漫 我一把揭開白布两入。 她就那樣靜靜地躺著,像睡著了一般敲才。 火紅的嫁衣襯著肌膚如雪裹纳。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,610評(píng)論 1 305
  • 那天紧武,我揣著相機(jī)與錄音剃氧,去河邊找鬼。 笑死阻星,一個(gè)胖子當(dāng)著我的面吹牛朋鞍,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播妥箕,決...
    沈念sama閱讀 40,352評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼番舆,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了矾踱?” 一聲冷哼從身側(cè)響起恨狈,我...
    開封第一講書人閱讀 39,257評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎呛讲,沒想到半個(gè)月后禾怠,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,717評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡贝搁,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,894評(píng)論 3 336
  • 正文 我和宋清朗相戀三年吗氏,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片雷逆。...
    茶點(diǎn)故事閱讀 40,021評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡弦讽,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情往产,我是刑警寧澤被碗,帶...
    沈念sama閱讀 35,735評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站仿村,受9級(jí)特大地震影響锐朴,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜蔼囊,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,354評(píng)論 3 330
  • 文/蒙蒙 一焚志、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧畏鼓,春花似錦酱酬、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,936評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至泼差,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間呵俏,已是汗流浹背堆缘。 一陣腳步聲響...
    開封第一講書人閱讀 33,054評(píng)論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留普碎,地道東北人吼肥。 一個(gè)月前我還...
    沈念sama閱讀 48,224評(píng)論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像麻车,于是被迫代替她去往敵國和親缀皱。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,974評(píng)論 2 355

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