iOS錄制視頻遇到的那些坎

先說一下我的視頻錄制的思路:

1.首先創建一個VC專門用來渲染和顯示視頻的控制器

2.在viewWillAppear中做好如下初始化準備錄音步驟:

#import "RecordVideoViewController.h"
//音視頻
#import <AVFoundation/AVFoundation.h>
#import <AssetsLibrary/AssetsLibrary.h>
//文件
#import "FCFileManager.h"
//網絡
#import "DRDAPIPostCall.h"
//提示
#import "UIView+Toast.h"

#define RGBA_COLOR(R, G, B, A) [UIColor colorWithRed:((R) / 255.0f) green:((G) / 255.0f) blue:((B) / 255.0f) alpha:A]

typedef void(^PropertyChangeBlock)(AVCaptureDevice *captureDevice);

@interface RecordVideoViewController ()<AVCaptureFileOutputRecordingDelegate>     //視頻文件輸出代理
@property (strong,nonatomic) AVCaptureSession *captureSession;                    //負責輸入和輸出設備之間的數據傳遞
@property (strong,nonatomic) AVCaptureDeviceInput *captureDeviceInput;            //負責從AVCaptureDevice獲得輸入數據
@property (strong,nonatomic) AVCaptureMovieFileOutput *captureMovieFileOutput;    //視頻輸出流
@property (strong,nonatomic) AVCaptureVideoPreviewLayer *captureVideoPreviewLayer;//相機拍攝預覽圖層
@property (assign,nonatomic) BOOL enableRotation;                                //是否允許旋轉(注意在視頻錄制過程中禁止屏幕旋轉)
@property (assign,nonatomic) CGRect *lastBounds;                                 //旋轉的前大小
@property (assign,nonatomic) UIBackgroundTaskIdentifier backgroundTaskIdentifier;//后臺任務標識
@property (weak, nonatomic) IBOutlet UIView *viewContainer;                      //本控制器
@property (weak, nonatomic) IBOutlet UIImageView *focusCursor;                   //聚焦光標
@property (weak, nonatomic) IBOutlet UIProgressView *videoProgress;              //加載進度條
@property (weak, nonatomic) IBOutlet UIButton *recordBtn;                        //錄屏按鈕
@property (weak, nonatomic) IBOutlet UILabel *recoderTipsLabel;                  //錄屏時間顯示標簽
@property (strong,nonatomic) NSTimer *mTimerForRecord;                           //錄屏定時器

@end

@implementation RecordVideoViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.
    
    //文字顏色
    [_recoderTipsLabel setTextColor:RGBA_COLOR(32, 192, 227, 1)];
}
- (IBAction)backButtonAction:(id)sender {
    //停止錄視頻
    [self.captureMovieFileOutput stopRecording];//停止錄制
    //關閉監聽
    [self removeNotification];
    //關閉定時器
    [_mTimerForRecord invalidate];
    _mTimerForRecord = nil;
    [self dismissViewControllerAnimated:YES completion:nil];
}

-(void)viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];
    //初始化會話
    _captureSession=[[AVCaptureSession alloc]init];
    if ([_captureSession canSetSessionPreset:AVCaptureSessionPreset1920x1080]) {//設置分辨率
        _captureSession.sessionPreset=AVCaptureSessionPreset1920x1080;
    }
    //獲得輸入設備
    AVCaptureDevice *captureDevice=[self getCameraDeviceWithPosition:AVCaptureDevicePositionBack];//取得后置攝像頭
    if (!captureDevice) {
        NSLog(@"取得后置攝像頭時出現問題.");
        return;
    }
    //添加一個音頻輸入設備
    AVCaptureDevice *audioCaptureDevice=[[AVCaptureDevice devicesWithMediaType:AVMediaTypeAudio] firstObject];
    
    
    NSError *error=nil;
    //根據輸入設備初始化設備輸入對象,用于獲得輸入數據
    _captureDeviceInput=[[AVCaptureDeviceInput alloc]initWithDevice:captureDevice error:&error];
    if (error) {
        NSLog(@"取得設備輸入對象時出錯,錯誤原因:%@",error.localizedDescription);
        return;
    }
    AVCaptureDeviceInput *audioCaptureDeviceInput=[[AVCaptureDeviceInput alloc]initWithDevice:audioCaptureDevice error:&error];
    if (error) {
        NSLog(@"取得設備輸入對象時出錯,錯誤原因:%@",error.localizedDescription);
        return;
    }
    //初始化設備輸出對象,用于獲得輸出數據
    _captureMovieFileOutput=[[AVCaptureMovieFileOutput alloc]init];
    
    //將設備輸入添加到會話中
    if ([_captureSession canAddInput:_captureDeviceInput]) {
        [_captureSession addInput:_captureDeviceInput];
        [_captureSession addInput:audioCaptureDeviceInput];
        AVCaptureConnection *captureConnection=[_captureMovieFileOutput connectionWithMediaType:AVMediaTypeVideo];
        if ([captureConnection isVideoStabilizationSupported ]) {
            captureConnection.preferredVideoStabilizationMode=AVCaptureVideoStabilizationModeAuto;
        }
    }
    
    //將設備輸出添加到會話中
    if ([_captureSession canAddOutput:_captureMovieFileOutput]) {
        [_captureSession addOutput:_captureMovieFileOutput];
    }
    
    //創建視頻預覽層,用于實時展示攝像頭狀態
    _captureVideoPreviewLayer=[[AVCaptureVideoPreviewLayer alloc]initWithSession:self.captureSession];
    NSLog(@"前:%i",[_captureVideoPreviewLayer connection].videoOrientation);
    //新增加

    
    [_captureVideoPreviewLayer connection].videoOrientation = (AVCaptureVideoOrientation)[[UIApplication sharedApplication] statusBarOrientation];

    NSLog(@"后:%i",[_captureVideoPreviewLayer connection].videoOrientation);
    
    CALayer *layer=self.viewContainer.layer;
    layer.masksToBounds=YES;
    
    _captureVideoPreviewLayer.frame=layer.bounds;
    NSLog(@"%@",NSStringFromCGRect(layer.bounds));
    
    _captureVideoPreviewLayer.videoGravity=AVLayerVideoGravityResizeAspectFill;//填充模式


    //將視頻預覽層添加到界面中
    //[layer addSublayer:_captureVideoPreviewLayer];
    [layer insertSublayer:_captureVideoPreviewLayer below:self.focusCursor.layer];
    
    _enableRotation=NO;
    [self addNotificationToCaptureDevice:captureDevice];
    [self addGenstureRecognizer];
}

#pragma mark - 計時器
- (void)startTimeLabel
{
    _recoderTipsLabel.text = @"00:00";
    _mTimerForRecord = [NSTimer timerWithTimeInterval:1 target:self selector:@selector(toSetRecFlags) userInfo:nil repeats:YES];                   //定時改變錄像標
    [[NSRunLoop currentRunLoop] addTimer:_mTimerForRecord forMode:NSRunLoopCommonModes];
    [_mTimerForRecord setFireDate:[NSDate distantPast]];
}

- (void)stopTimeLabel
{
    [_mTimerForRecord setFireDate:[NSDate distantFuture]];
    [_mTimerForRecord invalidate];
    _mTimerForRecord = nil;
    _recoderTipsLabel.text = @"00:00";
}

- (void)toSetRecFlags
{
    NSInteger value = [[[_recoderTipsLabel.text componentsSeparatedByString:@":"] objectAtIndex:0] integerValue]*60 + [[[_recoderTipsLabel.text componentsSeparatedByString:@":"] objectAtIndex:1] integerValue];
    
    value++;
    NSString *minute;
    NSString *second;
    
    if (value/60 > 9)
    {
        minute = [NSString stringWithFormat:@"%d",value/60];
    }
    else
    {
        minute = [NSString stringWithFormat:@"0%d",value/60];
    }
    
    if (value%60 > 9)
    {
        second = [NSString stringWithFormat:@"%d",value%60];
    }
    else
    {
        second = [NSString stringWithFormat:@"0%d",value%60];
    }
    
    [_recoderTipsLabel setTextColor:RGBA_COLOR(32, 192, 227, 1)];//RGBA(32, 192, 227, 1)//RGBA(201, 201, 201, 1)
    [_recoderTipsLabel setText:[NSString stringWithFormat:@"%@:%@",minute,second]];
}

#pragma mark 上傳視頻
- (IBAction)uploadVideoAction:(id)sender
{
    _videoProgress.hidden = NO;
    NSString *outputFielPath = [FCFileManager pathForTemporaryDirectoryWithPath:@"user_video.mp4"];
        
    DRDAPIPostCall *apiPost = [[DRDAPIPostCall alloc] init];
    [apiPost setApiCompletionHandler:^(id _Nonnull responseObject, NSError * _Nullable error) {
        if (error) {
            [self.view makeToast:[error description] duration:2.0 position:CSToastPositionCenter];
        }
    }];
    [apiPost setApiRequestConstructingBodyBlock:^(id<DRDMultipartFormData> _Nonnull formData) {
        NSData *videoData = [NSData dataWithContentsOfFile:outputFielPath];
        [formData appendPartWithFileData:videoData
                                    name:@"user_video"
                                fileName:@"user_video"
                                mimeType:@"video/mp4"];
    }];
    [apiPost setApiProgressBlock:^(NSProgress * _Nullable progress) {
        __weak typeof(self) weakSelf = self;
        dispatch_async(dispatch_get_main_queue(), ^{
            weakSelf.videoProgress.progress =  progress.fractionCompleted;
            weakSelf.recoderTipsLabel.text = [NSString stringWithFormat:@"上傳進度: %.2f%%", progress.fractionCompleted * 100];
        });

    }];
    [apiPost start];
}

#pragma mark 錄屏
-(BOOL)shouldAutorotate{
    return NO;
}

-(void)viewDidAppear:(BOOL)animated{
    [super viewDidAppear:animated];
    [self.captureSession startRunning];
}

-(void)viewDidDisappear:(BOOL)animated{
    [super viewDidDisappear:animated];
    [self.captureSession stopRunning];
}



//屏幕旋轉時調整視頻預覽圖層的方向
//-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration{
//    AVCaptureConnection *captureConnection=[self.captureVideoPreviewLayer connection];
//    captureConnection.videoOrientation=(AVCaptureVideoOrientation)toInterfaceOrientation;
//}
//旋轉后重新設置大小
//-(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation{
//    _captureVideoPreviewLayer.frame=self.viewContainer.bounds;
//}

-(void)dealloc{
    [self removeNotification];
}
//切換攝像頭
- (IBAction)toggleCapture:(id)sender {
    AVCaptureDevice *currentDevice=[self.captureDeviceInput device];
    AVCaptureDevicePosition currentPosition=[currentDevice position];
    [self removeNotificationFromCaptureDevice:currentDevice];
    
    AVCaptureDevice *toChangeDevice;
    AVCaptureDevicePosition toChangePosition=AVCaptureDevicePositionFront;
    if (currentPosition==AVCaptureDevicePositionUnspecified||currentPosition==AVCaptureDevicePositionFront) {
        toChangePosition=AVCaptureDevicePositionBack;
    }
    toChangeDevice=[self getCameraDeviceWithPosition:toChangePosition];
    [self addNotificationToCaptureDevice:toChangeDevice];
    //獲得要調整的設備輸入對象
    AVCaptureDeviceInput *toChangeDeviceInput=[[AVCaptureDeviceInput alloc]initWithDevice:toChangeDevice error:nil];
    
    //改變會話的配置前一定要先開啟配置,配置完成后提交配置改變
    [self.captureSession beginConfiguration];
    //移除原有輸入對象
    [self.captureSession removeInput:self.captureDeviceInput];
    [self.captureSession setSessionPreset:AVCaptureSessionPresetHigh];
    //添加新的輸入對象
    BOOL isAdded = [self.captureSession canAddInput:toChangeDeviceInput];
    if (isAdded) {
        [self.captureSession addInput:toChangeDeviceInput];
        self.captureDeviceInput=toChangeDeviceInput;
    }else{
        [self.captureSession addInput:self.captureDeviceInput];
    }

    
    //提交會話配置
    [self.captureSession commitConfiguration];
}
- (IBAction)startVideo:(id)sender {
    //根據設備輸出獲得連接
    AVCaptureConnection *captureConnection=[self.captureMovieFileOutput connectionWithMediaType:AVMediaTypeVideo];

    //根據連接取得設備輸出的數據
    if (![self.captureMovieFileOutput isRecording]) {
        self.enableRotation=NO;
        //開始計時
        [self startTimeLabel];
        //切換UI圖標
        [_recordBtn setImage:[UIImage imageNamed:@"RecoderBtn_Selected.png"] forState:UIControlStateNormal];
        //如果支持多任務則則開始多任務
        if ([[UIDevice currentDevice] isMultitaskingSupported]) {
            self.backgroundTaskIdentifier=[[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:nil];
        }
        //預覽圖層和視頻方向保持一致
        captureConnection.videoOrientation=[self.captureVideoPreviewLayer connection].videoOrientation;
        NSLog(@"%i",[self.captureVideoPreviewLayer connection].videoOrientation);

        NSString *outputFielPath=[NSTemporaryDirectory() stringByAppendingString:@"user_video.mp4"];
        if ([FCFileManager existsItemAtPath:outputFielPath]) {
            [FCFileManager removeItemAtPath:outputFielPath];
        }
        NSLog(@"save path is :%@",outputFielPath);
        NSURL *fileUrl=[NSURL fileURLWithPath:outputFielPath];
        [self.captureMovieFileOutput startRecordingToOutputFileURL:fileUrl recordingDelegate:self];
    }
    else{
        [self.captureMovieFileOutput stopRecording];//停止錄制
        [_recordBtn setImage:[UIImage imageNamed:@"RecoderBtn_Defalut.png"] forState:UIControlStateNormal];//切換UI圖標
        [self stopTimeLabel];//結束計時
    }
}



- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

#pragma mark - 視頻輸出代理
-(void)captureOutput:(AVCaptureFileOutput *)captureOutput didStartRecordingToOutputFileAtURL:(NSURL *)fileURL fromConnections:(NSArray *)connections{
    NSLog(@"開始錄制...");
}
-(void)captureOutput:(AVCaptureFileOutput *)captureOutput didFinishRecordingToOutputFileAtURL:(NSURL *)outputFileURL fromConnections:(NSArray *)connections error:(NSError *)error{
    NSLog(@"視頻錄制完成.");
    //視頻錄入完成之后在后臺將視頻存儲到相簿
    self.enableRotation=YES;
    UIBackgroundTaskIdentifier lastBackgroundTaskIdentifier=self.backgroundTaskIdentifier;
    self.backgroundTaskIdentifier=UIBackgroundTaskInvalid;
    ALAssetsLibrary *assetsLibrary=[[ALAssetsLibrary alloc]init];
    [assetsLibrary writeVideoAtPathToSavedPhotosAlbum:outputFileURL completionBlock:^(NSURL *assetURL, NSError *error) {
        if (error) {
            NSLog(@"保存視頻到相簿過程中發生錯誤,錯誤信息:%@",error.localizedDescription);
        }
        if (lastBackgroundTaskIdentifier!=UIBackgroundTaskInvalid) {
            [[UIApplication sharedApplication] endBackgroundTask:lastBackgroundTaskIdentifier];
        }
        NSLog(@"成功保存視頻到相簿.");
    }];
    
}

- (void)captureOutput:(AVCaptureFileOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection
{
    [connection setVideoOrientation:AVCaptureVideoOrientationLandscapeRight];
}

#pragma mark - 通知
/**
 *  給輸入設備添加通知
 */
-(void)addNotificationToCaptureDevice:(AVCaptureDevice *)captureDevice{
    //注意添加區域改變捕獲通知必須首先設置設備允許捕獲
    [self changeDeviceProperty:^(AVCaptureDevice *captureDevice) {
        captureDevice.subjectAreaChangeMonitoringEnabled=YES;
    }];
    NSNotificationCenter *notificationCenter= [NSNotificationCenter defaultCenter];
    //捕獲區域發生改變
    [notificationCenter addObserver:self selector:@selector(areaChange:) name:AVCaptureDeviceSubjectAreaDidChangeNotification object:captureDevice];
}
-(void)removeNotificationFromCaptureDevice:(AVCaptureDevice *)captureDevice{
    NSNotificationCenter *notificationCenter= [NSNotificationCenter defaultCenter];
    [notificationCenter removeObserver:self name:AVCaptureDeviceSubjectAreaDidChangeNotification object:captureDevice];
}
/**
 *  移除所有通知
 */
-(void)removeNotification{
    NSNotificationCenter *notificationCenter= [NSNotificationCenter defaultCenter];
    [notificationCenter removeObserver:self];
}

-(void)addNotificationToCaptureSession:(AVCaptureSession *)captureSession{
    NSNotificationCenter *notificationCenter= [NSNotificationCenter defaultCenter];
    //會話出錯
    [notificationCenter addObserver:self selector:@selector(sessionRuntimeError:) name:AVCaptureSessionRuntimeErrorNotification object:captureSession];
}

/**
 *  設備連接成功
 *
 *  @param notification 通知對象
 */
-(void)deviceConnected:(NSNotification *)notification{
    NSLog(@"設備已連接...");
}
/**
 *  設備連接斷開
 *
 *  @param notification 通知對象
 */
-(void)deviceDisconnected:(NSNotification *)notification{
    NSLog(@"設備已斷開.");
}
/**
 *  捕獲區域改變
 *
 *  @param notification 通知對象
 */
-(void)areaChange:(NSNotification *)notification{
    NSLog(@"捕獲區域改變...");
}

/**
 *  會話出錯
 *
 *  @param notification 通知對象
 */
-(void)sessionRuntimeError:(NSNotification *)notification{
    NSLog(@"會話發生錯誤.");
}

#pragma mark - 私有方法

/**
 *  取得指定位置的攝像頭
 *
 *  @param position 攝像頭位置
 *
 *  @return 攝像頭設備
 */
-(AVCaptureDevice *)getCameraDeviceWithPosition:(AVCaptureDevicePosition )position{
    NSArray *cameras= [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
    for (AVCaptureDevice *camera in cameras) {
        if ([camera position]==position) {
            return camera;
        }
    }
    return nil;
}

/**
 *  改變設備屬性的統一操作方法
 *
 *  @param propertyChange 屬性改變操作
 */
-(void)changeDeviceProperty:(PropertyChangeBlock)propertyChange{
    AVCaptureDevice *captureDevice= [self.captureDeviceInput device];
    NSError *error;
    //注意改變設備屬性前一定要首先調用lockForConfiguration:調用完之后使用unlockForConfiguration方法解鎖
    if ([captureDevice lockForConfiguration:&error]) {
        propertyChange(captureDevice);
        [captureDevice unlockForConfiguration];
    }else{
        NSLog(@"設置設備屬性過程發生錯誤,錯誤信息:%@",error.localizedDescription);
    }
}

/**
 *  設置閃光燈模式
 *
 *  @param flashMode 閃光燈模式
 */
-(void)setFlashMode:(AVCaptureFlashMode )flashMode{
    [self changeDeviceProperty:^(AVCaptureDevice *captureDevice) {
        if ([captureDevice isFlashModeSupported:flashMode]) {
            [captureDevice setFlashMode:flashMode];
        }
    }];
}
/**
 *  設置聚焦模式
 *
 *  @param focusMode 聚焦模式
 */
-(void)setFocusMode:(AVCaptureFocusMode )focusMode{
    [self changeDeviceProperty:^(AVCaptureDevice *captureDevice) {
        if ([captureDevice isFocusModeSupported:focusMode]) {
            [captureDevice setFocusMode:focusMode];
        }
    }];
}
/**
 *  設置曝光模式
 *
 *  @param exposureMode 曝光模式
 */
-(void)setExposureMode:(AVCaptureExposureMode)exposureMode{
    [self changeDeviceProperty:^(AVCaptureDevice *captureDevice) {
        if ([captureDevice isExposureModeSupported:exposureMode]) {
            [captureDevice setExposureMode:exposureMode];
        }
    }];
}
/**
 *  設置聚焦點
 *
 *  @param point 聚焦點
 */
-(void)focusWithMode:(AVCaptureFocusMode)focusMode exposureMode:(AVCaptureExposureMode)exposureMode atPoint:(CGPoint)point{
    [self changeDeviceProperty:^(AVCaptureDevice *captureDevice) {
        if ([captureDevice isFocusModeSupported:focusMode]) {
            [captureDevice setFocusMode:AVCaptureFocusModeAutoFocus];
        }
        if ([captureDevice isFocusPointOfInterestSupported]) {
            [captureDevice setFocusPointOfInterest:point];
        }
        if ([captureDevice isExposureModeSupported:exposureMode]) {
            [captureDevice setExposureMode:AVCaptureExposureModeAutoExpose];
        }
        if ([captureDevice isExposurePointOfInterestSupported]) {
            [captureDevice setExposurePointOfInterest:point];
        }
    }];
}

/**
 *  添加點按手勢,點按時聚焦
 */
-(void)addGenstureRecognizer{
    UITapGestureRecognizer *tapGesture=[[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tapScreen:)];
    [self.viewContainer addGestureRecognizer:tapGesture];
}
-(void)tapScreen:(UITapGestureRecognizer *)tapGesture{
    CGPoint point= [tapGesture locationInView:self.viewContainer];
    //將UI坐標轉化為攝像頭坐標
    CGPoint cameraPoint= [self.captureVideoPreviewLayer captureDevicePointOfInterestForPoint:point];
    [self setFocusCursorWithPoint:point];
    [self focusWithMode:AVCaptureFocusModeAutoFocus exposureMode:AVCaptureExposureModeAutoExpose atPoint:cameraPoint];
}

/**
 *  設置聚焦光標位置
 *
 *  @param point 光標位置
 */
-(void)setFocusCursorWithPoint:(CGPoint)point{
    self.focusCursor.center=point;
    self.focusCursor.transform=CGAffineTransformMakeScale(1.5, 1.5);
    self.focusCursor.alpha=1.0;
    [UIView animateWithDuration:1.0 animations:^{
        self.focusCursor.transform=CGAffineTransformIdentity;
    } completion:^(BOOL finished) {
        self.focusCursor.alpha=0;
        
    }];
}

- (UIInterfaceOrientationMask)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskLandscape;
}

@end

遇到的主要問題:
我是ipad頁面,當我翻轉ipad的時候,該頁面沒有跟著轉動,導致當我拿反pad的時候頁面是個反的。
解決的辦法就是上面的渲染頁面我把它做了以下的操作:

[_captureVideoPreviewLayer connection].videoOrientation = (AVCaptureVideoOrientation)[[UIApplication sharedApplication] statusBarOrientation];
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,527評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,687評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,640評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,957評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,682評論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,011評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,009評論 3 449
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,183評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,714評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,435評論 3 359
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,665評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,148評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,838評論 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,251評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,588評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,379評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,627評論 2 380

推薦閱讀更多精彩內容

  • 發現 關注 消息 iOS 第三方庫、插件、知名博客總結 作者大灰狼的小綿羊哥哥關注 2017.06.26 09:4...
    肇東周閱讀 12,179評論 4 61
  • 2017.02.22 可以練習,每當這個時候,腦袋就犯困,我這腦袋真是神奇呀,一說讓你做事情,你就犯困,你可不要太...
    Carden閱讀 1,366評論 0 1
  • 對于橫向的GridView,很多人會說,沒必要,用RecycleView就可以完成,但是,我就喜歡搞點特別的,...
    2c2z0閱讀 820評論 0 0
  • 今天從下載的APP《單讀》里面看到了一篇關于顧城的詩歌,我記住了出自于他的這句:黑夜給了我黑色的眼睛,我卻用它來尋...
    琉璃色的貓閱讀 206評論 0 0