iOS 掃碼(閃光燈览效、自動拉近放大)

需求:產(chǎn)品要實現(xiàn)類似微信掃碼一樣效果的功能,光線暗的時候虫几,能夠自動打開閃光燈(并出現(xiàn)閃光燈控制開關(guān)圖標(biāo)),然后用戶可以手動控制閃光燈的開關(guān)挽拔。
還有一個是實現(xiàn)自動拉近放大功能辆脸。


1.png

踩過的坑:當(dāng)時不知道是手凍還是什么,把videoPreView的引用類型寫成了weak螃诅,導(dǎo)致了鏡頭所在的layer加載不顯示啡氢,當(dāng)時查了好久沒找到問題,心態(tài)崩了术裸,找的小伙伴幫我排查倘是,最后他打斷點發(fā)現(xiàn)打印self.videoPreView的frame為(0,0袭艺,0搀崭,0)。我又自己看了一下,發(fā)現(xiàn)self.videoPreView為nil瘤睹,就看了一下屬性升敲。果然是屬性寫錯了,以后一定要謹(jǐn)慎細(xì)心轰传。真丟臉啊??

#import "QRCodeScanningViewController.h"
#import <AVFoundation/AVFoundation.h>
#import <ImageIO/ImageIO.h>
#import "GoodsDetailViewController.h"

@interface QRCodeScanningViewController ()<AVCaptureMetadataOutputObjectsDelegate,AVCaptureVideoDataOutputSampleBufferDelegate,UIGestureRecognizerDelegate>{
    BOOL bHadAutoVideoZoom;
}

@property (weak, nonatomic) IBOutlet UIButton *torchBtn;//燈泡開關(guān)
@property (weak, nonatomic) IBOutlet UILabel *torchStatusLabel;//燈泡底下的開關(guān)顯示

@property (weak, nonatomic) IBOutlet NSLayoutConstraint *scanBottomConstraint;
@property (weak, nonatomic) IBOutlet UIImageView *scanningBar;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *leftReturnBtnTopConstraint;

@property (nonatomic, strong) NSTimer *timer;
@property (nonatomic, strong) AVCaptureDevice *device;
@property (nonatomic, strong) AVCaptureSession *session;
@property (strong, nonatomic) AVCaptureDeviceInput * input;
@property (nonatomic, strong) AVCaptureVideoPreviewLayer *layer;
@property (nonatomic, strong) AVCaptureStillImageOutput *stillImageOutput;//拍照
@property (nonatomic, strong) UIView *videoPreView; ///視頻預(yù)覽顯示視圖
@property (nonatomic, assign) CGPoint centerPoint;//二維碼的中心點
@property (nonatomic, assign) BOOL isAutoOpen;//默認(rèn)NO 閃光燈



@end

@implementation QRCodeScanningViewController

-(void)viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];
    self.navigationController.navigationBar.hidden = YES;
}

- (void)viewWillDisappear:(BOOL)animated{
    [super viewWillDisappear:animated];
    self.navigationController.navigationBar.hidden = NO;
    [self turnTorchOn:NO];
    [self stopScanning];
}

- (void)viewDidLoad {
    [super viewDidLoad];
    [self  creatSubviews];
    [self scanCameraAuth];

}

#pragma mark - UI

- (void)creatSubviews{
    //默認(rèn)不顯示閃光燈
    [self.torchBtn setSelected:NO];
    self.torchBtn.hidden = self.torchStatusLabel.hidden =YES;
    //適配齊劉海
    self.leftReturnBtnTopConstraint.constant = (6+STATUSH);
    
}

- (void)scanCameraAuth{
    __weak typeof(self)  weakSelf = self;
    [self requestCameraPemissionWithResult:^(BOOL granted) {
        if (granted) {
            [weakSelf startScanning];
            [weakSelf networkStatusAlert];
        } else {
            [weakSelf showAlertToPromptCameraAuthorization];
        }
    }];

}

#pragma mark - btn

- (IBAction)returnBack:(UIButton *)sender {
    [self leftBarButtonItemReturnAction];
}

- (IBAction)lighting:(UIButton *)sender {
    sender.selected = !sender.selected;
    [self turnTorchOn:sender.selected];
}


#pragma mark - Helpers
- (void)startScanning {
    self.timer = [NSTimer scheduledTimerWithTimeInterval:0.02 target:self selector:@selector(animateScanningBar) userInfo:nil repeats:YES];

    if (!self.layer) {
        AVCaptureSession *session = [[AVCaptureSession alloc] init];
        session.sessionPreset = AVCaptureSessionPresetHigh;

        /// Input.
        self.device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
        self.input = [AVCaptureDeviceInput deviceInputWithDevice:self.device error:nil];

        /// Output. Must work in a serial queue.
        dispatch_queue_t serialQueue = dispatch_queue_create("ScanningQueue", NULL);
        //掃描結(jié)果 自動放大
        AVCaptureMetadataOutput *output = [[AVCaptureMetadataOutput alloc] init];
        [output setMetadataObjectsDelegate:self queue:serialQueue];
        //閃光燈
        AVCaptureVideoDataOutput *dataOutput = [[AVCaptureVideoDataOutput alloc] init];
        [dataOutput setSampleBufferDelegate:self queue:dispatch_get_main_queue()];

//        CGRect cropRect = CGRectMake((SCREEN_WIDTH-220)*0.5, SCREEN_HEIGHT*0.5-60, 220, 220);
//        if (!CGRectEqualToRect(cropRect,CGRectZero)){
//            output.rectOfInterest = cropRect;
//        }

        self.stillImageOutput = [[AVCaptureStillImageOutput alloc] init];
        NSDictionary *outputSettings = [[NSDictionary alloc] initWithObjectsAndKeys:AVVideoCodecJPEG, AVVideoCodecKey,nil];
        [self.stillImageOutput setOutputSettings:outputSettings];

        if ([session canAddInput:self.input]) {
            [session addInput:self.input];
        }
        if ([session canAddOutput:output]) {
            [session addOutput:output];
        }
        if ([session canAddOutput:dataOutput]) {
            [session addOutput:dataOutput];
        }
        if ([session canAddOutput:self.stillImageOutput]){
            [session addOutput:self.stillImageOutput];
        }

        /* 掃條形碼
        AVMetadataObjectTypeEAN13Code,
        AVMetadataObjectTypeEAN8Code,
        AVMetadataObjectTypeUPCECode,
        AVMetadataObjectTypeCode39Code,
        AVMetadataObjectTypeCode39Mod43Code,
        AVMetadataObjectTypeCode93Code,
        AVMetadataObjectTypeCode128Code,
        AVMetadataObjectTypePDF417Code
        */

        NSArray *types = @[AVMetadataObjectTypeQRCode];
        NSMutableArray *typesAvailable = [NSMutableArray array];
        for (NSString *type in types) {
            if ([output.availableMetadataObjectTypes containsObject:type]) [typesAvailable addObject:type];
        }
        output.metadataObjectTypes = typesAvailable;

        /// Preview layer.
        AVCaptureVideoPreviewLayer *layer = [AVCaptureVideoPreviewLayer layerWithSession:session];
        layer.videoGravity = AVLayerVideoGravityResizeAspectFill;
        layer.frame = SCREEN_BOUNDS;

        [self.view insertSubview:self.videoPreView atIndex:0];
        [self.videoPreView.layer insertSublayer:layer atIndex:0];

        self.layer = layer;
        self.session = session;
    }

    [self.session startRunning];
    bHadAutoVideoZoom = NO;//還未自動拉近的值
    [self setVideoScale:1 ];//設(shè)置拉近倍數(shù)為1

}

- (void)stopScanning {
    if (self.session.isRunning) {
        [self.session stopRunning];
    }

    if (self.timer.isValid) {
        [self.timer invalidate];
        self.timer = nil;
    }
}

- (void)animateScanningBar {
    int constant = (int)self.scanBottomConstraint.constant;
    if (constant > 0) {
        constant --;
    }else {
        constant = 218;
    }
    self.scanBottomConstraint.constant = constant;
}

#pragma mark - get
- (UIView *)videoPreView{
    if (!_videoPreView) {
        UIView *videoView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT)];
        videoView.backgroundColor = [UIColor clearColor];
        _videoPreView = videoView;
    }
    return _videoPreView;
}

#pragma mark - Delegate Methods AVCaptureMetadataOutputObjectsDelegate
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection {
    NetworkStatus internetStatus = [Helper internetStatus];
    if (internetStatus == NotReachable) {
        return;
    }
    //識別掃碼類型
    NSString *result;
    for(AVMetadataObject *current in metadataObjects){
        if ([current isKindOfClass:[AVMetadataMachineReadableCodeObject class]]){
            NSString *scannedResult = [(AVMetadataMachineReadableCodeObject *) current stringValue];
            if (scannedResult && ![scannedResult isEqualToString:@""]){
                result = scannedResult;
            }
        }
    }
//    NSLog(@"掃描%@", result);
    if (result.length<1) {
        return;
    }

    if (!bHadAutoVideoZoom) {
        AVMetadataMachineReadableCodeObject *obj = (AVMetadataMachineReadableCodeObject *)[self.layer transformedMetadataObjectForMetadataObject:metadataObjects.lastObject];
        dispatch_async(dispatch_get_main_queue(), ^{
            [self changeVideoScale:obj];
        });
        bHadAutoVideoZoom  =YES;
        return;
    }
    if ([result hasPrefix:@"https"]||[result hasPrefix:@"http"]) {
        [self stopScanning];
        dispatch_async(dispatch_get_main_queue(), ^{
            [self handlerJump:result];
        });
    }else{
        __weak typeof(self) weakSelf = self;
        dispatch_async(dispatch_get_main_queue(), ^{
            [Helper addAlerViewOrAlertControllerWithTitle:@"提示" message: @"無效的二維碼" buttonTitle:@"我知道了" forViewController:weakSelf];
        });
    }
}

//處理跳轉(zhuǎn)
- (void)handlerJump:(NSString *)resultString{
     NSDictionary *dic = [NSDictionary dictionaryWithDictionary:[Helper getDictionaryFormURL:resultString]];
    if(![resultString containsString:@"nqyong.com"]){
        __weak typeof(self) weakSelf = self;
        NSString *msg = [NSString stringWithFormat:@"可能存在安全風(fēng)險驴党,是否打開此鏈接?\n%@",resultString];
        [self addTwoAlertControllerAction:@"提示" message:msg leftTitle:@"打開鏈接" rightTitle:@"取消" leftAction:^(UIAlertAction * _Nonnull action) {
            [weakSelf passScanningGoNextBaseWebviewTitle:@"" updateTitle:YES url:resultString contactKefu:NO];
        } rightAction:^(UIAlertAction * _Nonnull action) {
            [weakSelf leftBarButtonItemReturnAction];
        }];
    }else if ([resultString containsString:@"www.nqyong.com/downloadsApp.html"]){
         NSString *jumpString = [NSString stringWithFormat:@"https://store-h5.nqyong.com/channelShop?appid=%@",dic[@"appid"]];
        [self passScanningGoNextBaseWebviewTitle:@"商品列表" updateTitle:YES url:jumpString contactKefu:NO];
     }else if ([resultString containsString:@"h5.nqyong.com/goodsDetail?"]) {
        GoodsDetailViewController *GoodsDetailVC = (GoodsDetailViewController *)[UIStoryboard vcFrom:Goods identifier:[NSString stringWithFormat:@"%@",GoodsDetailViewController.class]];
        GoodsDetailVC.hidesBottomBarWhenPushed = YES;
        GoodsDetailVC.goodsID = dic[@"id"];
        GoodsDetailVC.goodsName = @"";
        [DataKeeper sharedKeeper].appId = dic[@"appid"];
        [self passScanningGoNextVC:GoodsDetailVC];
     }else{
        [self passScanningGoNextBaseWebviewTitle:@"" updateTitle:YES url:resultString contactKefu:NO];
     }
}

//跳轉(zhuǎn)到webview之前获茬,去掉掃碼頁
- (void)passScanningGoNextBaseWebviewTitle:(NSString *)title updateTitle:(BOOL)updateTitle url:(NSString *)url contactKefu:(BOOL)contactKefu{
    if (url.length == 0) return;
    RootWebViewController *root = [[RootWebViewController alloc]init];
    root.hidesBottomBarWhenPushed = YES;
    root.aTitle = title;
    root.contactKefu = contactKefu;
    root.updateTitle = updateTitle;
    root.request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];
    [self passScanningGoNextVC:root];
}
//設(shè)置navabar的代理路由
- (void)passScanningGoNextVC:(UIViewController *)vc{
    NSMutableArray *vcArray = [NSMutableArray arrayWithArray:self.navigationController.viewControllers];
    int index = (int)[vcArray indexOfObject:self];
    if (vcArray.count<2) {
        return;
    }
    [vcArray removeObjectAtIndex:index];
    [vcArray addObject: vc];
    [self.navigationController setViewControllers:vcArray animated:NO];
}

#pragma mark - AVCaptureVideoDataOutputSampleBufferDelegate

- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection{
    CFDictionaryRef metadataDict = CMCopyDictionaryOfAttachments(NULL,sampleBuffer, kCMAttachmentMode_ShouldPropagate);
    NSDictionary *metadata = [[NSMutableDictionary alloc] initWithDictionary:(__bridge NSDictionary*)metadataDict];
    CFRelease(metadataDict);
    NSDictionary *exifMetadata = [[metadata objectForKey:(NSString *)kCGImagePropertyExifDictionary] mutableCopy];
    float brightnessValue = [[exifMetadata objectForKey:(NSString *)kCGImagePropertyExifBrightnessValue] floatValue];
    // brightnessValue 值代表光線強(qiáng)度港庄,值越小代表光線越暗
//    NSLog(@"光線%f", brightnessValue);
    if (brightnessValue <= -2 &&!self.isAutoOpen) {
        self.isAutoOpen = YES;
        [self turnTorchOn:YES];
        dispatch_async(dispatch_get_main_queue(), ^{
            [self.torchBtn setSelected:YES];
            self.torchBtn.hidden = self.torchStatusLabel.hidden= NO;
        });
    }
}

#pragma mark -  打開/關(guān)閉手電筒
- (void)turnTorchOn:(BOOL)on{
    if ([self.device hasTorch] && [self.device hasFlash]){

        dispatch_async(dispatch_get_main_queue(), ^{
            self.torchStatusLabel.text = on?@"點擊關(guān)閉":@"點擊開啟";
        });

        [self.device lockForConfiguration:nil];
        if (on) {
            [self.device setTorchMode:AVCaptureTorchModeOn];
            [self.device setFlashMode:AVCaptureFlashModeOn];
        } else {
            [self.device setTorchMode:AVCaptureTorchModeOff];
            [self.device setFlashMode:AVCaptureFlashModeOff];
        }
        [self.device unlockForConfiguration];
    } else {
        [Helper addAlerViewOrAlertControllerWithTitle:@"提示" message:@"當(dāng)前設(shè)備沒有閃光燈,不能提供手電筒功能"  buttonTitle:@"我知道了" forViewController:self];
    }
}

#pragma mark - 二維碼自動拉近

- (void)changeVideoScale:(AVMetadataMachineReadableCodeObject *)objc
{
    NSArray *array = objc.corners;
    NSLog(@"cornersArray = %@",array);
    CGPoint point = CGPointZero;
    // 把字典轉(zhuǎn)換為點恕曲,存在point里攘轩,成功返回true 其他false
    CGPointMakeWithDictionaryRepresentation((__bridge CFDictionaryRef)array[0], &point);

    NSLog(@"X:%f -- Y:%f",point.x,point.y);
    CGPoint point2 = CGPointZero;
    CGPointMakeWithDictionaryRepresentation((__bridge CFDictionaryRef)array[2], &point2);
    NSLog(@"X:%f -- Y:%f",point2.x,point2.y);

    self.centerPoint = CGPointMake((point.x + point2.x) / 2, (point.y + point2.y) / 2);
    CGFloat scace = 150 / (point2.x - point.x); //當(dāng)二維碼圖片寬小于150,進(jìn)行放大
    [self setVideoScale:scace];
    return;
}

- (void)setVideoScale:(CGFloat)scale
{
    [self.input.device lockForConfiguration:nil];

    AVCaptureConnection *videoConnection = [self connectionWithMediaType:AVMediaTypeVideo fromConnections:[[self stillImageOutput] connections]];
    CGFloat maxScaleAndCropFactor = ([[self.stillImageOutput connectionWithMediaType:AVMediaTypeVideo] videoMaxScaleAndCropFactor])/16;

    if (scale > maxScaleAndCropFactor){
        scale = maxScaleAndCropFactor;
    }else if (scale < 1){
        scale = 1;
    }

    CGFloat zoom = scale / videoConnection.videoScaleAndCropFactor;
    videoConnection.videoScaleAndCropFactor = scale;

    [self.input.device unlockForConfiguration];

    CGAffineTransform transform = self.videoPreView.transform;

    //自動拉近放大
    if (scale == 1) {
        self.videoPreView.transform = CGAffineTransformScale(transform, zoom, zoom);
        CGRect rect = self.videoPreView.frame;
        rect.origin = CGPointZero;
        self.videoPreView.frame = rect;
    } else {
        CGFloat x = self.videoPreView.center.x - self.centerPoint.x;
        CGFloat y = self.videoPreView.center.y - self.centerPoint.y;
        CGRect rect = self.videoPreView.frame;
        rect.origin.x = rect.size.width / 2.0 * (1 - scale);
        rect.origin.y = rect.size.height / 2.0 * (1 - scale);
        rect.origin.x += x * zoom;
        rect.origin.y += y * zoom;
        rect.size.width = rect.size.width * scale;
        rect.size.height = rect.size.height * scale;

        [UIView animateWithDuration:.5f animations:^{
            self.videoPreView.transform = CGAffineTransformScale(transform, zoom, zoom);
            self.videoPreView.frame = rect;
        } completion:^(BOOL finished) {
        }];
    }

    NSLog(@"放大%f",zoom);
}

- (AVCaptureConnection *)connectionWithMediaType:(NSString *)mediaType fromConnections:(NSArray *)connections
{
    for ( AVCaptureConnection *connection in connections ) {
        for ( AVCaptureInputPort *port in [connection inputPorts] ) {
            if ( [[port mediaType] isEqual:mediaType] ) {
                return connection;
            }
        }
    }
    return nil;
}

//#pragma mark 手勢拉近/遠(yuǎn) 界面
//- (void)cameraInitOver{
//    UIPinchGestureRecognizer *pinch = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(pinchDetected:)];
//    pinch.delegate = self;
//    [self.view addGestureRecognizer:pinch];
//}
//
//- (void)pinchDetected:(UIPinchGestureRecognizer*)recogniser
//{
//    self.effectiveScale = self.beginGestureScale * recogniser.scale;
//    if (self.effectiveScale < 1.0){
//        self.effectiveScale = 1.0;
//    }
//    [self setVideoScale:self.effectiveScale pinch:YES];
//}
//
//- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
//{
//    if ( [gestureRecognizer isKindOfClass:[UIPinchGestureRecognizer class]] ) {
//        _beginGestureScale = _effectiveScale;
//    }
//    return YES;
//}

#pragma mark - 相機(jī)權(quán)限Alert

- (void)requestCameraPemissionWithResult:(void(^)( BOOL granted))completion
{
    if ([AVCaptureDevice respondsToSelector:@selector(authorizationStatusForMediaType:)])
    {
        AVAuthorizationStatus permission =
        [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];

        switch (permission) {
            case AVAuthorizationStatusAuthorized:
                completion(YES);
                break;
            case AVAuthorizationStatusDenied:
            case AVAuthorizationStatusRestricted:
                completion(NO);
                break;
            case AVAuthorizationStatusNotDetermined:{
                [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo
                                         completionHandler:^(BOOL granted) {

                 dispatch_async(dispatch_get_main_queue(), ^{
                     if (granted) {
                         completion(true);
                     } else {
                         completion(false);
                     }
                 });
               }];
            }
            break;
        }
    }
}

- (void)showAlertToPromptCameraAuthorization {
    UIAlertController *alertCtr = [UIAlertController alertControllerWithTitle:@"提示" message:@"您的相機(jī)功能沒有打開,去“設(shè)置>拿趣用”設(shè)置一下吧" preferredStyle:UIAlertControllerStyleAlert];
    [alertCtr addAction:[UIAlertAction actionWithTitle:@"關(guān)閉" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
        dispatch_async(dispatch_get_main_queue(), ^(void){
            [self leftBarButtonItemReturnAction];
        });
    }]];
    [alertCtr addAction:[UIAlertAction actionWithTitle:@"去設(shè)置" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
        dispatch_async(dispatch_get_main_queue(), ^(void){
            [self.navigationController popToRootViewControllerAnimated:YES];
            [Helper openURL:UIApplicationOpenSettingsURLString];
        });
    }]];
    [self presentViewController:alertCtr animated:YES completion:nil];
}

-(void)addTwoAlertControllerAction:(NSString *)title message:(NSString *)message leftTitle:(NSString *)leftTitle rightTitle:(NSString *)rightTitle leftAction:(void (^)(UIAlertAction * _Nonnull action))leftAction  rightAction:(void (^)(UIAlertAction * _Nonnull action))rightAction{
    UIAlertController *alertCtr = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert];
    [alertCtr addAction:[UIAlertAction actionWithTitle:leftTitle style:UIAlertActionStyleDefault handler:leftAction]];
    [alertCtr addAction:[UIAlertAction actionWithTitle:rightTitle style:UIAlertActionStyleDefault handler:rightAction]];
    [self presentViewController:alertCtr animated:YES completion:nil];
}

-(void)networkStatusAlert{
    NetworkStatus internetStatus = [Helper internetStatus];
    switch (internetStatus) {
        case NotReachable:{
            __weak typeof(self) weakSelf = self;
            dispatch_async(dispatch_get_main_queue(), ^{
                [weakSelf addTwoAlertControllerAction:@"提示" message:@"您的WLAN與蜂窩移動網(wǎng)功能沒有打開,去“設(shè)置>拿趣用”設(shè)置一下吧" leftTitle:@"關(guān)閉" rightTitle:@"去設(shè)置" leftAction:^(UIAlertAction * _Nonnull action) {
                } rightAction:^(UIAlertAction * _Nonnull action) {
                    [weakSelf.navigationController popToRootViewControllerAnimated:YES];
                    [Helper openURL:UIApplicationOpenSettingsURLString];
                }];
            });
        }
            break;

        default:
            break;
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末傻工,一起剝皮案震驚了整個濱河市浙炼,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌斩个,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,451評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異率翅,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)袖迎,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,172評論 3 394
  • 文/潘曉璐 我一進(jìn)店門冕臭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人燕锥,你說我怎么就攤上這事辜贵。” “怎么了归形?”我有些...
    開封第一講書人閱讀 164,782評論 0 354
  • 文/不壞的土叔 我叫張陵托慨,是天一觀的道長。 經(jīng)常有香客問我暇榴,道長厚棵,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,709評論 1 294
  • 正文 為了忘掉前任蔼紧,我火速辦了婚禮婆硬,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘奸例。我一直安慰自己彬犯,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,733評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著躏嚎,像睡著了一般蜜自。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上卢佣,一...
    開封第一講書人閱讀 51,578評論 1 305
  • 那天重荠,我揣著相機(jī)與錄音,去河邊找鬼虚茶。 笑死戈鲁,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的嘹叫。 我是一名探鬼主播婆殿,決...
    沈念sama閱讀 40,320評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼罩扇!你這毒婦竟也來了婆芦?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,241評論 0 276
  • 序言:老撾萬榮一對情侶失蹤喂饥,失蹤者是張志新(化名)和其女友劉穎消约,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體员帮,經(jīng)...
    沈念sama閱讀 45,686評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡或粮,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,878評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了捞高。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片氯材。...
    茶點故事閱讀 39,992評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖硝岗,靈堂內(nèi)的尸體忽然破棺而出氢哮,到底是詐尸還是另有隱情,我是刑警寧澤辈讶,帶...
    沈念sama閱讀 35,715評論 5 346
  • 正文 年R本政府宣布命浴,位于F島的核電站,受9級特大地震影響贱除,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜媳溺,卻給世界環(huán)境...
    茶點故事閱讀 41,336評論 3 330
  • 文/蒙蒙 一月幌、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧悬蔽,春花似錦扯躺、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,912評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽倍啥。三九已至,卻和暖如春澎埠,著一層夾襖步出監(jiān)牢的瞬間虽缕,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,040評論 1 270
  • 我被黑心中介騙來泰國打工蒲稳, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留氮趋,地道東北人。 一個月前我還...
    沈念sama閱讀 48,173評論 3 370
  • 正文 我出身青樓江耀,卻偏偏與公主長得像剩胁,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子祥国,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,947評論 2 355