AVPlayer播放網(wǎng)絡(luò)音樂

下載地址:AVPlayer播放網(wǎng)絡(luò)音樂

音樂播放并展示到界面上需要我們實(shí)現(xiàn)的功能如下:

1蒜哀、(核心)播放器通過一個(gè)網(wǎng)絡(luò)鏈接播放音樂
2戳寸、(基本)播放器的常用操作:暫停泡垃、播放、上一首贝椿、下一首等等
3、(基本)監(jiān)聽該音樂的播放進(jìn)度陷谱、獲取音樂的總時(shí)間烙博、當(dāng)前播放時(shí)間
4、(基本)監(jiān)聽改播放器狀態(tài):
?????(1)媒體加載狀態(tài)
?????(2)數(shù)據(jù)緩沖狀態(tài)
?????(3)播放完畢狀態(tài)
5烟逊、(可選)Remote Control控制音樂的播放
6习勤、(可選)Now Playing Center展示正在播放的音樂

功能實(shí)現(xiàn)

我自己寫了一個(gè)管理類 (里面封裝了大部分播放邏輯)
已完成功能:播放、暫停焙格、上下一首图毕、單曲循環(huán)、隨機(jī)播放眷唉、后臺(tái)播放予颤、鎖屏信息。
第一次寫這種管理類冬阳,可能會(huì)有點(diǎn)復(fù)雜蛤虐,不太容易看懂 。 我把歌曲的信息也存在里面了肝陪。

.h 文件

#import <Foundation/Foundation.h>
#import <AVFoundation/AVFoundation.h>
#import "SongsMessageModel.h"

typedef NS_ENUM(NSInteger, playerType) {
    AVPlayerTypeNormal = 0,           //正常循環(huán)播放狀態(tài)
    AVPlayerTypeRandom,                 //隨機(jī)播放
    AVPlayerTypeSingle,                 //單曲循環(huán)
};

/**返回緩沖進(jìn)度*/
typedef void(^loadTime)(NSString *str);
/**返回 當(dāng)前進(jìn)度驳庭、總時(shí)長(zhǎng)、slider 最大值和當(dāng)前值*/
typedef void(^returnTime)(NSString *current,NSString *total,float max,float value);
/**返回 AVPlayerItem的序號(hào)(換背景圖氯窍、歌手饲常、歌曲)*/
typedef void(^returnImage)(NSInteger index);

@interface AVPlayerManager : NSObject

/**存放AVplayerItem的數(shù)組*/
@property(nonatomic,strong)NSMutableArray *musicArray;

//**歌曲地址數(shù)組*/
@property(nonatomic,strong)NSMutableArray *songArray;// 是否進(jìn)入的已存在的歌單!
/**海報(bào)數(shù)組*/
@property(nonatomic,strong)NSMutableArray *imageArray;
/**歌手?jǐn)?shù)組*/
@property(nonatomic,strong)NSMutableArray *singerArray;
/**歌曲名數(shù)組*/
@property(nonatomic,strong)NSMutableArray *songNameArray;

/**AVPlayer播放器*/
@property (nonatomic, strong) AVPlayer *player;

/**播放模式*/
@property (nonatomic,assign) NSInteger playerType;

/**當(dāng)前播放時(shí)間*/
@property(nonatomic,assign) float currentPlayTime;
/**當(dāng)前緩沖時(shí)間*/
@property(nonatomic,assign)NSTimeInterval currentLoadTime;

/**slider最大值*/
@property(nonatomic,assign) float silderMaxValue;
/**slider當(dāng)前值*/
@property(nonatomic,assign) float silderValue;
/***/
@property(nonatomic,strong) NSString *playTime;
/**總時(shí)長(zhǎng)*/
@property(nonatomic,strong) NSString *totalTime;
/**緩沖提示*/
@property(nonatomic,strong) NSString *loadTime;

@property(nonatomic,strong)loadTime block;
@property(nonatomic,strong)returnTime block1;
@property(nonatomic,strong) returnImage block2;

/**通知 獲取當(dāng)前播放狀態(tài) 控制按鈕狀態(tài)*/
@property(nonatomic,strong) NSNotificationCenter * center;
/**判斷是否是從歌單列表進(jìn)入播放器 還是 直接在進(jìn)入播放器*/
@property(nonatomic,assign) BOOL listInto;


+ (instancetype)shareManager;
//**播放*/
- (void)musicPlayerWithArray:(NSArray *)musicArray andIndex:(NSInteger )index;
//**正在播放時(shí)   播放指定歌曲狼讨, */
- (void)musicPlayerWithIndex:(NSInteger )index;
//*播放
-(void)playMusic;
//*暫停
-(void)pasueMusic贝淤;
//**下一首*/
- (void)nextSong;
//**上一首*/
- (void)lastSong;
//**進(jìn)度條 調(diào)節(jié) */
- (void)playerProgressWithProgressFloat:(CGFloat)progressFloat;

//**移除觀察者*/
-(void)removeObserver;

/**獲取當(dāng)前播放序號(hào)*/
-(NSInteger )getcurrentItem;

.m 文件

#import "AVPlayerManager.h"
#import <MediaPlayer/MediaPlayer.h>

@implementation AVPlayerManager
{
    id timeObserve;// 為 當(dāng)前AVPlayerItem 添加觀察者獲取各種播放狀態(tài)
}

+(instancetype)shareManager{
    static AVPlayerManager *manager = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        manager = [AVPlayerManager new];
    });
    return manager;
}

-(instancetype)init{
    if (self =[super init]) {
        _playerType = AVPlayerTypeNormal;
    }
    return self;
}

//播放器懶加載
-(AVPlayer *)player{
    if (!_player) {
        _player = [AVPlayer new];
    }
    return _player;
}

-(NSMutableArray *)musicArray{
    if (!_musicArray) {
        _musicArray = [NSMutableArray array];
        
        _center = [NSNotificationCenter defaultCenter];
    }
    return _musicArray;
}

//播放指定url
- (void)musicPlayerWithURL:(NSURL *)playerItemURL{
    
    //創(chuàng)建要播放的資源
    AVPlayerItem *playerItem = [[AVPlayerItem alloc]initWithURL:playerItemURL];
    //添加觀察者
    //播放當(dāng)前資源
    [self.player replaceCurrentItemWithPlayerItem:playerItem];
}


-(void)musicPlayerWithIndex:(NSInteger)index{
     // 播放AVPlayerItem數(shù)組中指定序號(hào)歌曲 (此操作之前需要將上一個(gè)item 的 觀察者移除 并將 seekTime 設(shè)置為0 確保下次播放從頭開始)
    [self.player replaceCurrentItemWithPlayerItem:self.musicArray[index]];
    
    self.block2([self.musicArray indexOfObject:self.player.currentItem]);
    
    [self addObserver];
    
}

//重新添加新的歌單列表進(jìn)來
- (void)musicPlayerWithArray:(NSArray *)musicArray andIndex:(NSInteger )index{
    //首先移除之前的歌單列表 再 重新添加
    [self.songArray removeAllObjects];
    [self.songArray addObjectsFromArray:musicArray];
    
    for (NSString * obj in musicArray) {
        AVPlayerItem *songItem = [[AVPlayerItem alloc] initWithURL:[NSURL URLWithString:obj]];
        [self.musicArray addObject:songItem];
    }
    //播放歌單列表序號(hào)對(duì)應(yīng)的歌曲
    [self.player replaceCurrentItemWithPlayerItem:self.musicArray[index]];
    //對(duì)當(dāng)前item 添加觀察者
    [self addObserver];
}

//播放
-(void)playMusic{
    [self.player play];
}
//暫停
-(void)pasueMusic{
    [self.player pause];
}

//上一首
-(void)lastSong{
    
    [self removeObserver];//先移除當(dāng)前 觀察者
    
    [self.player.currentItem seekToTime:(kCMTimeZero) completionHandler:^(BOOL finished) {
        
        if (self.playerType == AVPlayerTypeNormal) {//順序循環(huán)播放
            //判斷當(dāng)前歌曲是否是第一首歌曲,如果是跳轉(zhuǎn)到最后一首歌
            if ([self.musicArray indexOfObject:self.player.currentItem] ==0) {
                [self.player replaceCurrentItemWithPlayerItem:self.musicArray.lastObject];
            }else{
                [self.player replaceCurrentItemWithPlayerItem:self.musicArray[[self.musicArray  indexOfObject:self.player.currentItem]-1]];
            }
            
        }else if (self.playerType == AVPlayerTypeRandom){//隨機(jī)播放
            NSInteger random = arc4random_uniform((int)self.musicArray.count);
            NSLog(@"%ld",random);
            
            [self.player replaceCurrentItemWithPlayerItem:self.musicArray[arc4random_uniform((int)self.musicArray.count)]];
        }else if (self.playerType ==AVPlayerTypeSingle){ //單曲循環(huán)在自動(dòng)切換歌曲時(shí)進(jìn)行判斷
            //判斷當(dāng)前歌曲是否是第一首歌曲政供,如果是跳轉(zhuǎn)到最后一首歌
            if ([self.musicArray indexOfObject:self.player.currentItem] ==0) {
                [self.player replaceCurrentItemWithPlayerItem:self.musicArray.lastObject];
            }else{
                [self.player replaceCurrentItemWithPlayerItem:self.musicArray[[self.musicArray  indexOfObject:self.player.currentItem]-1]];
            }
        }
        
        [self playMusic];
        //放回對(duì)應(yīng)歌曲的信息
         self.block2([self.musicArray indexOfObject:self.player.currentItem]);
        [self addObserver];//添加觀察者
    }];
}
//下一首
-(void)nextSong{
    [self removeObserver];
    
    [self.player.currentItem seekToTime:(kCMTimeZero) completionHandler:^(BOOL finished) {
       
        if (self.playerType == AVPlayerTypeNormal) {
            //判斷當(dāng)前歌曲是否是最后一首歌曲播聪,如果是跳轉(zhuǎn)到第一首歌
            if ([self.musicArray indexOfObject:self.player.currentItem]+1 == self.musicArray.count) {
                [self.player replaceCurrentItemWithPlayerItem:self.musicArray.firstObject];
            }else{
                [self.player replaceCurrentItemWithPlayerItem:self.musicArray[[self.musicArray  indexOfObject:self.player.currentItem]+1]];
            }
            
        }else if (self.playerType == AVPlayerTypeRandom){
          [self.player replaceCurrentItemWithPlayerItem:self.musicArray[arc4random_uniform((int)self.musicArray.count)]];
        }else if (self.playerType == AVPlayerTypeSingle){
            //判斷當(dāng)前歌曲是否是最后一首歌曲朽基,如果是跳轉(zhuǎn)到第一首歌
            if ([self.musicArray indexOfObject:self.player.currentItem]+1 == self.musicArray.count) {
                [self.player replaceCurrentItemWithPlayerItem:self.musicArray.firstObject];
            }else{
                [self.player replaceCurrentItemWithPlayerItem:self.musicArray[[self.musicArray  indexOfObject:self.player.currentItem]+1]];
            }
        }
        
        [self playMusic];
        self.block2([self.musicArray indexOfObject:self.player.currentItem]);
        [self addObserver];
    }];
    
}

//獲取 當(dāng)前播放歌曲在AVPlayerItem中的 序號(hào)
-(NSInteger )getcurrentItem{
    return [self.musicArray indexOfObject:self.player.currentItem];
}

//將slider的值傳入使 歌曲進(jìn)度 前進(jìn)或后退
-(void)playerProgressWithProgressFloat:(CGFloat)progressFloat{
    if (progressFloat > self.currentLoadTime) {
        NSDictionary *dict = @{@"播放狀態(tài)":@0};
        [self.center postNotificationName:@"playOrPasue" object:self userInfo:dict];
    }
    [self.player seekToTime:CMTimeMake(progressFloat, 1.0)];
}

//接受播放完成的通知 開始下一首
- (void)playbackFinished:(NSNotification *)notice {
    //判斷是否是單曲循環(huán)  是的話 移除觀察者 將當(dāng)前進(jìn)度調(diào)為0 重新播放
    if (self.playerType == AVPlayerTypeSingle) {
        
       [self removeObserver];
       [self.player.currentItem seekToTime:kCMTimeZero];
        
       [self musicPlayerWithIndex:[self getcurrentItem]];
       [self playMusic];
    }else{
       [self nextSong];
    }
    
}

//為當(dāng)前播放的item 添加觀察者
-(void)addObserver{
    __weak typeof(self) weekSelf = self;
    __weak AVPlayer *weekPlayer = self.player;
    
    //觀察該item 是否能播放
    [self.player.currentItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];
    //觀察該item 加載進(jìn)度
    [self.player.currentItem addObserver:self forKeyPath:@"loadedTimeRanges" options:NSKeyValueObservingOptionNew context:nil];
    
    //AVPlayer 自帶方法:返回歌曲 播放進(jìn)度 信息
    timeObserve = [self.player addPeriodicTimeObserverForInterval:CMTimeMake(1.0, 1.0) queue:dispatch_get_main_queue() usingBlock:^(CMTime time) {
        [weekSelf updateLockedScreenMusic:[weekSelf getcurrentItem]];
        
        float current = CMTimeGetSeconds(time);
        float total = CMTimeGetSeconds(weekPlayer.currentItem.duration);
        weekSelf.currentPlayTime = current;
        if (total > 0) {
            weekSelf.silderMaxValue = total;
        }else{
            weekSelf.silderMaxValue = 300;
        };
        weekSelf.silderValue = current;

        if (current) {
            weekSelf.playTime =[weekSelf timetranstation:[NSString stringWithFormat:@"%.f",current]];
            weekSelf.totalTime =[weekSelf timetranstation:[NSString stringWithFormat:@"%.f",total]];
            
            //判斷歌曲播完 后發(fā)出通知 -132行 接受通知
            if (current == total) { //    total - current <=1  有時(shí)會(huì)導(dǎo)致不能正常切換歌曲
                [[NSNotificationCenter defaultCenter] addObserver:weekSelf selector:@selector(playbackFinished:) name:AVPlayerItemDidPlayToEndTimeNotification object:weekPlayer.currentItem];
            }
            
            //返回 播放界面所需要的內(nèi)容。
            weekSelf.block1(weekSelf.playTime,weekSelf.totalTime,weekSelf.silderMaxValue,weekSelf.silderValue);
        }
    }];
}

//移除對(duì)當(dāng)前item 的觀察 通知
-(void)removeObserver{
    if (timeObserve) {
        [[NSNotificationCenter defaultCenter] removeObserver:self];
        [self.player.currentItem removeObserver:self forKeyPath:@"loadedTimeRanges"];
        [self.player.currentItem removeObserver:self forKeyPath:@"status"];
        [self.player removeTimeObserver:timeObserve];
        
    }
}

//觀察者
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
    AVPlayerItem * songItem = object;
    NSDictionary *dict = @{@"播放狀態(tài)":@1};
    if ([keyPath isEqualToString:@"status"]) {
        switch (self.player.status) {
            case AVPlayerStatusUnknown:
                //  BASE_INFO_FUN(@"KVO:未知狀態(tài)离陶,此時(shí)不能播放");
                break;
            case AVPlayerStatusReadyToPlay:
                // self.status = SUPlayStatusReadyToPlay;
                //  BASE_INFO_FUN(@"KVO:準(zhǔn)備完畢稼虎,可以播放");
                [self.center postNotificationName:@"playOrPasue" object:self userInfo:dict];
                [self.player play];
                break;
            case AVPlayerStatusFailed:
                //  BASE_INFO_FUN(@"KVO:加載失敗,網(wǎng)絡(luò)或者服務(wù)器出現(xiàn)問題");
                break;
            default:
                break;
        }
    }else  if ([keyPath isEqualToString:@"loadedTimeRanges"]) {
        NSArray * array = songItem.loadedTimeRanges;
        CMTimeRange timeRange = [array.firstObject CMTimeRangeValue]; //本次緩沖的時(shí)間范圍
        NSTimeInterval totalBuffer = CMTimeGetSeconds(timeRange.start) + CMTimeGetSeconds(timeRange.duration); //緩沖總長(zhǎng)度
        self.currentLoadTime = totalBuffer;
        
        float total = CMTimeGetSeconds(songItem.duration);
      //  NSLog(@"共緩沖%.0f%",totalBuffer/total*100); 計(jì)算緩沖進(jìn)度
        self.loadTime =[NSString stringWithFormat:@"正在緩沖%.0f%",totalBuffer/total*100];
        if ([[NSString stringWithFormat:@"%.0f",totalBuffer/total*100] isEqualToString:@"100"]) {
            self.loadTime =@"";
        }else{
            self.loadTime =[NSString stringWithFormat:@"正在緩沖%.0f%",totalBuffer/total*100];
        }
        CGFloat currentPlayTime =  self.currentPlayTime;
       
        //緩沖完成時(shí)間大于當(dāng)前播放時(shí)間5s時(shí)通知播放器繼續(xù)播放 否則暫停
        if (totalBuffer > currentPlayTime +5) {
//            NSDictionary *dict = @{@"播放狀態(tài)":@1};
//            [self.center postNotificationName:@"playOrPasue" object:self userInfo:dict];
        }else{
            NSDictionary *dict = @{@"播放狀態(tài)":@0};
            [self.center postNotificationName:@"playOrPasue" object:self userInfo:dict];
        }
        
        NSLog(@"%f ----%f",total,totalBuffer);
        if (totalBuffer + 1 > total) {
            NSDictionary *dict = @{@"播放狀態(tài)":@1};
            [self.center postNotificationName:@"playOrPasue" object:self userInfo:dict];
        }
        self.block(self.loadTime);
    }
}

#pragma 秒數(shù)轉(zhuǎn)為分鐘
-(NSString *)timetranstation:(NSString *)time{
    NSString *returnTime =[NSString string];
    NSInteger total = [time integerValue];
    
    returnTime =[NSString stringWithFormat:@"%02ld:%02ld",total/60,total%60];
    return returnTime;
}


#pragma mark - 鎖屏?xí)r候的設(shè)置招刨,效果需要在真機(jī)上才可以看到
- (void)updateLockedScreenMusic:(NSInteger )index{
    // 播放信息中心
    MPNowPlayingInfoCenter *center = [MPNowPlayingInfoCenter defaultCenter];
    
    // 初始化播放信息
    NSMutableDictionary *info = [NSMutableDictionary dictionary];
    // 專輯名稱
//    info[MPMediaItemPropertyAlbumTitle] = [sel];
    // 歌手
    info[MPMediaItemPropertyArtist] = self.singerArray[index];
    // 歌曲名稱
    info[MPMediaItemPropertyTitle] =  self.songNameArray[index];
    // 設(shè)置圖片
    info[MPMediaItemPropertyArtwork] = [[MPMediaItemArtwork alloc] initWithImage:[UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@",self.imageArray[index]]]]]];
    // 設(shè)置持續(xù)時(shí)間(歌曲的總時(shí)間)
    [info setObject:[NSNumber numberWithFloat:CMTimeGetSeconds([self.player.currentItem duration])] forKey:MPMediaItemPropertyPlaybackDuration];
    // 設(shè)置當(dāng)前播放進(jìn)度
    [info setObject:[NSNumber numberWithFloat:CMTimeGetSeconds([self.player.currentItem currentTime])] forKey:MPNowPlayingInfoPropertyElapsedPlaybackTime];
    
    // 切換播放信息
    center.nowPlayingInfo = info;
    
}

第一次寫霎俩,如果哪位大神耐心看了,希望多給一點(diǎn)指點(diǎn)计济,不足的地方指出來茸苇。我要多學(xué)習(xí)學(xué)習(xí)!B偌拧学密!

demo中的網(wǎng)絡(luò)地址來自于 阿里星球 , 因?yàn)槭窃诰€播放传藏,所以在真機(jī)上面跑會(huì)有點(diǎn)卡 腻暮,希望大神指點(diǎn)!需要怎么處理毯侦?

參考鏈接:iOS音頻篇:使用AVPlayer播放網(wǎng)絡(luò)音樂

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末哭靖,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子侈离,更是在濱河造成了極大的恐慌试幽,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,423評(píng)論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件卦碾,死亡現(xiàn)場(chǎng)離奇詭異铺坞,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)洲胖,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,147評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門济榨,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人绿映,你說我怎么就攤上這事擒滑。” “怎么了叉弦?”我有些...
    開封第一講書人閱讀 157,019評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵丐一,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我卸奉,道長(zhǎng)钝诚,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,443評(píng)論 1 283
  • 正文 為了忘掉前任榄棵,我火速辦了婚禮凝颇,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘疹鳄。我一直安慰自己拧略,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,535評(píng)論 6 385
  • 文/花漫 我一把揭開白布瘪弓。 她就那樣靜靜地躺著垫蛆,像睡著了一般。 火紅的嫁衣襯著肌膚如雪腺怯。 梳的紋絲不亂的頭發(fā)上袱饭,一...
    開封第一講書人閱讀 49,798評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音呛占,去河邊找鬼虑乖。 笑死,一個(gè)胖子當(dāng)著我的面吹牛晾虑,可吹牛的內(nèi)容都是我干的疹味。 我是一名探鬼主播,決...
    沈念sama閱讀 38,941評(píng)論 3 407
  • 文/蒼蘭香墨 我猛地睜開眼帜篇,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼糙捺!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起笙隙,我...
    開封第一講書人閱讀 37,704評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤洪灯,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后竟痰,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體签钩,經(jīng)...
    沈念sama閱讀 44,152評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,494評(píng)論 2 327
  • 正文 我和宋清朗相戀三年凯亮,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了边臼。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,629評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡假消,死狀恐怖柠并,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情富拗,我是刑警寧澤臼予,帶...
    沈念sama閱讀 34,295評(píng)論 4 329
  • 正文 年R本政府宣布,位于F島的核電站啃沪,受9級(jí)特大地震影響粘拾,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜创千,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,901評(píng)論 3 313
  • 文/蒙蒙 一缰雇、第九天 我趴在偏房一處隱蔽的房頂上張望入偷。 院中可真熱鬧,春花似錦械哟、人聲如沸疏之。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,742評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽锋爪。三九已至,卻和暖如春爸业,著一層夾襖步出監(jiān)牢的瞬間其骄,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,978評(píng)論 1 266
  • 我被黑心中介騙來泰國打工扯旷, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留拯爽,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,333評(píng)論 2 360
  • 正文 我出身青樓薄霜,卻偏偏與公主長(zhǎng)得像某抓,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子惰瓜,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,499評(píng)論 2 348

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