iOS簡(jiǎn)單的AVAudioRecorder錄音器解決方案

前言

AVAudioRecorder的簡(jiǎn)單用法,通過(guò)AVAudioRecorder進(jìn)行錄音拍鲤。將錄制好的音頻保存的沙盒中。
內(nèi)容簡(jiǎn)單汞扎,牛繞行季稳。

介紹

DEMO主要特點(diǎn)如下:
1、設(shè)置最大錄音時(shí)間澈魄;
2景鼠、設(shè)置最小錄音時(shí)間;
3痹扇、文件保存為aac格式铛漓;
4、通過(guò)沙盒直接獲取錄音文件帘营;
5票渠、代理回調(diào)獲取錄音時(shí)的音量大小芬迄;
6问顷、判斷麥克風(fēng)權(quán)限等;

核心代碼

1禀梳、關(guān)于錄音器的創(chuàng)建

- (BOOL)createRecorder {
    if (!_recorder) {
        if (!_recorderParamsDictionary) {
            return NO;
        }
        NSError *error;
        _recorder = [[AVAudioRecorder alloc] initWithURL:[self fileURL]
                                                settings:self.recorderParamsDictionary
                                                   error:&error];
        _recorder.delegate = self;
        [_recorder prepareToRecord];
        if (!error) {
            return YES;
        }else {
            return NO;
        }
    }
    return YES;
}

2杜窄、設(shè)置采樣率等

// 設(shè)置錄音格式 @(kAudioFormatMPEG4AAC)
- (void)setObjectFormat:(NSObject *)format // 設(shè)置錄音格式 @(kAudioFormatMPEG4AAC)
                   rate:(NSObject *)rate // 設(shè)置錄音采樣率,8000是電話采樣率 @(8000)
                channel:(NSObject *)channel // 設(shè)置通道 @(1)
      linearPCMBitDepth:(NSObject *)linearPCMBitDepth // 每個(gè)采樣點(diǎn)位數(shù) @(8)
        linearPCMIsFloat:(NSObject *)linearPCMIsFloat /*是否使用浮點(diǎn)數(shù)采樣 @(YES)*/ {
    //設(shè)置錄音格式
    [self.recorderParamsDictionary setObject:format forKey:AVFormatIDKey];
    self.audioFormatID = (AudioFormatID)[[NSString stringWithFormat:@"%@",format] intValue];
    //設(shè)置錄音采樣率算途,8000是電話采樣率塞耕,對(duì)于一般錄音已經(jīng)夠了
    [self.recorderParamsDictionary setObject:rate forKey:AVSampleRateKey];
    //設(shè)置通道,這里采用單聲道
    [self.recorderParamsDictionary setObject:channel forKey:AVNumberOfChannelsKey];
    //每個(gè)采樣點(diǎn)位數(shù),分為8、16嘴瓤、24扫外、32
    [self.recorderParamsDictionary setObject:linearPCMBitDepth forKey:AVLinearPCMBitDepthKey];
    //是否使用浮點(diǎn)數(shù)采樣
    [self.recorderParamsDictionary setObject:linearPCMIsFloat forKey:AVLinearPCMIsFloatKey];
}

以上是核心代碼莉钙,通過(guò)自己的理解,加以修改筛谚,形成自己的錄音器磁玉。

.h 中的所有代碼

//
//  DKRecordManager.h
//
//  Created by 王亞振 on 2019/10/29.
//  Copyright ? 2019. All rights reserved.
//

#import <UIKit/UIKit.h>

typedef enum : NSUInteger {
    DKRecordManagerAudioAuthStatusUnknow,
    DKRecordManagerAudioAuthStatusNoAuth,
    DKRecordManagerAudioAuthStatusAuth
} DKRecordManagerAudioAuthStatus;

@protocol DKRecordManagerDelegate <NSObject>
@optional
/// 時(shí)間進(jìn)度條 每1秒反饋一次
/// @param time time
- (void)recordManagerDelegateTimeProgress:(NSInteger)time;
/// level進(jìn)度條 每0.5秒反饋一次
/// @param level level
- (void)recordManagerDelegateLevel:(NSInteger)level;
/// 錄音結(jié)束,倒計(jì)時(shí)時(shí)間
/// @param end end
- (void)recordManagerDelegateTimeEnd:(BOOL)end;
/// 錄音取消驾讲,倒計(jì)時(shí)時(shí)間
/// @param cancel cancel
- (void)recordManagerCancel:(BOOL)cancel;
/// 錄音結(jié)束
/// @param success YES||NO
- (void)recordManagerDelegateRecordEnd:(BOOL)success timeout:(BOOL)timeout duration:(NSInteger)duration;
/// 錄音結(jié)束
/// @param success YES||NO
- (void)recordManagerDelegateRecordEnd:(BOOL)success timeLess:(BOOL)timeLess duration:(NSInteger)duration;
/// 錄音音量 0~1
/// @param meter meter
- (void)recordManagerDelegateMeter:(CGFloat)meter;
@end

@interface DKRecordManager : NSObject

+ (DKRecordManager *)sharedManager;
@property (assign, nonatomic) id <DKRecordManagerDelegate> delegate;

/// 音量檢測(cè)
/// @param able able
- (void)setMeteringEnable:(BOOL)able;
/// 設(shè)置最大時(shí)間
/// @param time 最大時(shí)間
- (void)setMaxRecordTime:(NSInteger)time;
/// 設(shè)置最小時(shí)間
/// @param time 最小時(shí)間
- (void)setMinRecordTime:(NSInteger)time;
/// 通配參數(shù)
/// @param format format
/// @param rate rate
/// @param channel channel
/// @param linearPCMBitDepth linearPCMBitDepth
/// @param linearPCMIsFloat linearPCMIsFloat
- (void)setObjectFormat:(NSObject *)format // 設(shè)置錄音格式 @(kAudioFormatMPEG4AAC)
                   rate:(NSObject *)rate // 設(shè)置錄音采樣率蚊伞,8000是電話采樣率 @(8000)
                channel:(NSObject *)channel // 設(shè)置通道 @(1)
      linearPCMBitDepth:(NSObject *)linearPCMBitDepth // 每個(gè)采樣點(diǎn)位數(shù) @(8)
       linearPCMIsFloat:(NSObject *)linearPCMIsFloat; // 是否使用浮點(diǎn)數(shù)采樣 @(YES)
/// 必須先設(shè)置參數(shù)
- (BOOL)createRecorder;
/// 刪除錄音recorder
- (void)removeRecorder;
/// 開(kāi)始錄音
- (void)startRecorder;
/// 結(jié)束錄音
- (void)stopRecorder;
/// 移除錄音文件
- (BOOL)removeRecordFile;
/// 獲取錄音文件
- (NSURL *)getFileURL;
/// 移除代理
- (void)removeDelegate;
/// 取消
- (void)cancelRecorder;

#pragma mark --
#pragma mark -- PRIVATE 工具類

/// 獲取權(quán)限
+ (DKRecordManagerAudioAuthStatus)getAudioAuth;
@end

.m 中的所有代碼

//
//  DKRecordManager.m
//
//  Created by 王亞振 on 2019/10/29.
//  Copyright ? 2019 All rights reserved.
//

#import "DKRecordManager.h"
#import <AVFoundation/AVFoundation.h>

#define DK_FILE_CACHE_NAME @"/DK_FILE_CACHE_NAME"
@interface DKRecordManager ()<AVAudioRecorderDelegate>
/// 錄音時(shí)長(zhǎng)
@property (assign, nonatomic) NSInteger currentRecordTime;
/// 錄音最大時(shí)長(zhǎng)
@property (assign, nonatomic) NSInteger maxRecordTime;
/// 錄音最小時(shí)長(zhǎng) 0 無(wú)限制
@property (assign, nonatomic) NSInteger minRecordTime;
/// 錄音時(shí)長(zhǎng)定時(shí)器
@property (strong, nonatomic) dispatch_source_t waitingTimer;
/// 錄音音量監(jiān)測(cè)定時(shí)器
@property (strong, nonatomic) dispatch_source_t meterTimer;
/// 錄音對(duì)象
@property (strong, nonatomic) AVAudioRecorder *recorder;
/// 錄音參數(shù)集
@property (strong, nonatomic) NSMutableDictionary *recorderParamsDictionary;
/// 錄音格式 format kAudioFormatMPEG4AAC
@property (assign, nonatomic) AudioFormatID audioFormatID;
/// 監(jiān)聽(tīng)時(shí)間是否結(jié)束
@property (assign, nonatomic) BOOL timeout;
/// 是否監(jiān)聽(tīng)l音量
@property (assign, nonatomic) BOOL meter;
@property (assign, nonatomic) BOOL isCancel;
@end

@implementation DKRecordManager

+ (DKRecordManager *)sharedManager {
    static DKRecordManager *sharedManager = nil;
    static dispatch_once_t predicate;
    dispatch_once(&predicate, ^{
        sharedManager = [[DKRecordManager alloc] init];
    });
    return sharedManager;
}

#pragma mark --
#pragma mark -- PRIVATE 錄音區(qū)

/// 必須先設(shè)置參數(shù)
- (BOOL)createRecorder {
    if (!_recorder) {
        if (!_recorderParamsDictionary) {
            return NO;
        }
        NSError *error;
        _recorder = [[AVAudioRecorder alloc] initWithURL:[self fileURL]
                                                settings:self.recorderParamsDictionary
                                                   error:&error];
        _recorder.delegate = self;
        [_recorder prepareToRecord];
        if (!error) {
            return YES;
        }else {
            return NO;
        }
    }
    return YES;
}
/// 刪除錄音recorder
- (void)removeRecorder {
    [_recorder stop];
    _recorder = nil;
    _recorderParamsDictionary = nil;
    [self removeRecordFile];
}
/// 開(kāi)始錄音
- (void)startRecorder {
    self.isCancel = NO;
    if (self.recorder == nil) {
        return;
    }
    
    // 音量
    self.recorder.meteringEnabled = self.meter;
    if (self.meter) {
        [self startMeterTime];
    }
    
    // 錄音時(shí)長(zhǎng)
    self.currentRecordTime = 0;
    
    // 錄音
    NSError *error;
    AVAudioSession *audioSession = [AVAudioSession sharedInstance];
    [audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:&error];
    [audioSession setActive:YES error:nil];
    if (!error) {
        self.timeout = NO;
        [self.recorder record];
        [self startTime];
    }else {
        NSLog(@"無(wú)法錄音");
    }
}
/// 結(jié)束錄音
- (void)stopRecorder {
    [self.recorder stop];
    [self stopTimer];
    [self stopMeterTimer];
    if ([self.delegate respondsToSelector:@selector(recordManagerDelegateTimeProgress:)]) {
        [self.delegate recordManagerDelegateTimeProgress:0];
    }
    if ([self.delegate respondsToSelector:@selector(recordManagerDelegateLevel:)]) {
        [self.delegate recordManagerDelegateLevel:0];
    }
}
/// 移除錄音文件
- (BOOL)removeRecordFile  {
    [self.recorder stop];
    return [self.recorder deleteRecording];
}
/// 獲取錄音文件
- (NSURL *)getFileURL {
    return [self fileURL];
}
/// 移除代理
- (void)removeDelegate {
    self.delegate = nil;
}
/// 監(jiān)測(cè)音量
- (void)meterTimerMethod {
    if (!self.recorder.meteringEnabled) {
        return;
    }
    // 更新測(cè)量值
    [self.recorder updateMeters];
    // 取得第一個(gè)通道的音頻,注意音頻強(qiáng)度范圍時(shí)-160到0
    float power = [self.recorder averagePowerForChannel:0];
    CGFloat progress = (1.0 / 160.0) * (power + 160.0);
    NSLog(@"meterTimerMethod == %.2f",progress);
    if ([self.delegate respondsToSelector:@selector(recordManagerDelegateMeter:)]) {
        [self.delegate recordManagerDelegateMeter:progress];
    }
}
/// 取消
- (void)cancelRecorder {
    self.isCancel = YES;
    [self stopRecorder];
}

#pragma mark --
#pragma mark -- PRIVATE 參數(shù)設(shè)置區(qū)
/// 音量檢測(cè)
/// @param able able
- (void)setMeteringEnable:(BOOL)able {
    self.meter = able;
}
- (void)setMaxRecordTime:(NSInteger)maxRecordTime {
    if (maxRecordTime == 0) {
        _maxRecordTime = INTMAX_MAX;
    }else if (time < 0) {
        _maxRecordTime = -1;
        NSLog(@"無(wú)效時(shí)間");
    }else {
        _maxRecordTime = maxRecordTime;
    }
}
- (void)setMinRecordTime:(NSInteger)time {
    if (time == 0) {
        _minRecordTime = INTMAX_MIN;
    }else if (time < 0) {
        _minRecordTime = -1;
        NSLog(@"無(wú)效時(shí)間");
    }else {
        _minRecordTime = time;
    }
}
// 設(shè)置錄音格式 @(kAudioFormatMPEG4AAC)
- (void)setObjectFormat:(NSObject *)format // 設(shè)置錄音格式 @(kAudioFormatMPEG4AAC)
                   rate:(NSObject *)rate // 設(shè)置錄音采樣率吮铭,8000是電話采樣率 @(8000)
                channel:(NSObject *)channel // 設(shè)置通道 @(1)
      linearPCMBitDepth:(NSObject *)linearPCMBitDepth // 每個(gè)采樣點(diǎn)位數(shù) @(8)
        linearPCMIsFloat:(NSObject *)linearPCMIsFloat /*是否使用浮點(diǎn)數(shù)采樣 @(YES)*/ {
    //設(shè)置錄音格式
    [self.recorderParamsDictionary setObject:format forKey:AVFormatIDKey];
    self.audioFormatID = (AudioFormatID)[[NSString stringWithFormat:@"%@",format] intValue];
    //設(shè)置錄音采樣率时迫,8000是電話采樣率,對(duì)于一般錄音已經(jīng)夠了
    [self.recorderParamsDictionary setObject:rate forKey:AVSampleRateKey];
    //設(shè)置通道,這里采用單聲道
    [self.recorderParamsDictionary setObject:channel forKey:AVNumberOfChannelsKey];
    //每個(gè)采樣點(diǎn)位數(shù),分為8谓晌、16掠拳、24、32
    [self.recorderParamsDictionary setObject:linearPCMBitDepth forKey:AVLinearPCMBitDepthKey];
    //是否使用浮點(diǎn)數(shù)采樣
    [self.recorderParamsDictionary setObject:linearPCMIsFloat forKey:AVLinearPCMIsFloatKey];
}
- (NSMutableDictionary *)recorderParamsDictionary {
    if (!_recorderParamsDictionary) {
        _recorderParamsDictionary = [NSMutableDictionary dictionaryWithCapacity:0];
    }
    return _recorderParamsDictionary;
}

#pragma mark --
#pragma mark -- PRIVATE 地址相關(guān)處理

+ (NSString *)cacheDictionary {
    NSString *cacheDictionary = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
    NSLog(@"cacheDictionary -- %@",cacheDictionary);
    return cacheDictionary;
}
- (NSString *)appendFileName {
    NSString *address;
    if (self.audioFormatID == kAudioFormatMPEG4AAC) {
        address = @"aac";
    }
    NSString *appendFileName = [NSString stringWithFormat:@"%@%@.%@",[DKRecordManager cacheDictionary],DK_FILE_CACHE_NAME,address];
    return appendFileName;
}
- (NSURL *)fileURL {
    NSURL *url = [NSURL URLWithString:[self appendFileName]];
    return url;
}

#pragma mark --
#pragma mark -- PRIVATE 權(quán)限判斷

/// 獲取權(quán)限
+ (DKRecordManagerAudioAuthStatus)getAudioAuth {
    AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeAudio];
    switch (authStatus) {
        case AVAuthorizationStatusNotDetermined:
        // 被拒絕
        {
            return DKRecordManagerAudioAuthStatusNoAuth;
        }
        break;
        case AVAuthorizationStatusRestricted:
        // 未授權(quán)扎谎,家長(zhǎng)限制
        {
            return DKRecordManagerAudioAuthStatusNoAuth;
        }
        break;
        case AVAuthorizationStatusDenied:
        // 玩家未授權(quán)
        {
            return DKRecordManagerAudioAuthStatusUnknow;
        }
        break;
        case AVAuthorizationStatusAuthorized:
        // 玩家授權(quán)
        {
            return DKRecordManagerAudioAuthStatusAuth;
        }
        break;
        default:
            return DKRecordManagerAudioAuthStatusUnknow;
        break;
    }
}

#pragma mark --
#pragma mark -- PRIVATE 定時(shí)器相關(guān)

- (void)startTime {
    if (self.maxRecordTime == 0) {
        return;
    }
    [self stopTimer];
    __weak DKRecordManager *weakSelf = self;
    __block NSInteger time = 0;
    NSInteger timeSpace = 1;
    dispatch_queue_t queue = dispatch_get_main_queue();
    self.waitingTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
    dispatch_time_t start = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC));
    uint64_t interval = (uint64_t)(timeSpace * NSEC_PER_SEC);
    dispatch_source_set_timer(self.waitingTimer, start, interval, 0);
    dispatch_source_set_event_handler(self.waitingTimer, ^{
        // do something
        dispatch_async(dispatch_get_main_queue(), ^{
            if (weakSelf.maxRecordTime == 0) {
                // 時(shí)間未到碳想,繼續(xù)錄音
                if ([weakSelf.delegate respondsToSelector:@selector(recordManagerDelegateTimeProgress:)]) {
                    [weakSelf.delegate recordManagerDelegateTimeProgress:time];
                }
                NSLog(@"錄音時(shí)間 == %ld",time);
            }else {
                if (time > weakSelf.maxRecordTime) {
                    weakSelf.timeout = YES;
                    // 錄音時(shí)間到
                    if ([weakSelf.delegate respondsToSelector:@selector(recordManagerDelegateTimeEnd:)]) {
                        [weakSelf.delegate recordManagerDelegateTimeEnd:YES];
                    }
                    weakSelf.isCancel = YES;
                    [weakSelf stopRecorder];
                }else {
                    // 時(shí)間未到,繼續(xù)錄音
                    if ([weakSelf.delegate respondsToSelector:@selector(recordManagerDelegateTimeProgress:)]) {
                        [weakSelf.delegate recordManagerDelegateTimeProgress:time];
                    }
                    NSLog(@"錄音時(shí)間 == %ld",time);
                }
            }
        });
        time ++;
        weakSelf.currentRecordTime = time;
    });
    dispatch_resume(self.waitingTimer);
}
- (void)stopTimer {
    if (_waitingTimer) {
        dispatch_cancel(_waitingTimer);
        _waitingTimer = nil;
    }
}
- (void)startMeterTime {
    [self stopMeterTimer];
    __weak DKRecordManager *weakSelf = self;
    CGFloat timeSpace = 0.1;
    dispatch_queue_t queue = dispatch_get_main_queue();
    self.meterTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
    dispatch_time_t start = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC));
    uint64_t interval = (uint64_t)(timeSpace * NSEC_PER_SEC);
    dispatch_source_set_timer(self.meterTimer, start, interval, 0);
    dispatch_source_set_event_handler(self.meterTimer, ^{
        // do something
        dispatch_async(dispatch_get_main_queue(), ^{
            [weakSelf meterTimerMethod];
        });
    });
    dispatch_resume(self.meterTimer);
}
- (void)stopMeterTimer {
    if (_meterTimer) {
        dispatch_cancel(_meterTimer);
        _meterTimer = nil;
    }
}

#pragma mark --
#pragma mark -- DELEGATE <AVAudioRecorderDelegate>

- (void)audioRecorderDidFinishRecording:(AVAudioRecorder *)recorder successfully:(BOOL)flag {
    if (self.isCancel) {
        if ([self.delegate respondsToSelector:@selector(recordManagerCancel:)]) {
            [self.delegate recordManagerCancel:YES];
        }
        return;
    }
    if (self.minRecordTime > 0) {
        if (self.currentRecordTime < self.minRecordTime) {
            if ([self.delegate respondsToSelector:@selector(recordManagerDelegateRecordEnd:timeLess:duration:)]) {
                [self.delegate recordManagerDelegateRecordEnd:flag timeLess:YES duration:self.currentRecordTime];
            }
            return;
        }else {
            if ([self.delegate respondsToSelector:@selector(recordManagerDelegateRecordEnd:timeout:duration:)]) {
                [self.delegate recordManagerDelegateRecordEnd:flag timeout:self.timeout duration:self.currentRecordTime];
            }
        }
    }else {
        if ([self.delegate respondsToSelector:@selector(recordManagerDelegateRecordEnd:timeout:duration:)]) {
            [self.delegate recordManagerDelegateRecordEnd:flag timeout:self.timeout duration:self.currentRecordTime];
        }
    }
}
- (void)audioRecorderEncodeErrorDidOccur:(AVAudioRecorder *)recorder error:(NSError * __nullable)error {
    if (self.isCancel) {
        if ([self.delegate respondsToSelector:@selector(recordManagerCancel:)]) {
            [self.delegate recordManagerCancel:YES];
        }
        return;
    }
    if ([self.delegate respondsToSelector:@selector(recordManagerDelegateRecordEnd:timeout:duration:)]) {
        [self.delegate recordManagerDelegateRecordEnd:NO timeout:self.timeout duration:self.currentRecordTime];
    }
    [self stopTimer];
    [self stopMeterTimer];
}

@end


WX20210429-135620.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末毁靶,一起剝皮案震驚了整個(gè)濱河市胧奔,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌预吆,老刑警劉巖龙填,帶你破解...
    沈念sama閱讀 216,372評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異拐叉,居然都是意外死亡岩遗,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)凤瘦,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)宿礁,“玉大人,你說(shuō)我怎么就攤上這事蔬芥“鹁福” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,415評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵笔诵,是天一觀的道長(zhǎng)返吻。 經(jīng)常有香客問(wèn)我,道長(zhǎng)乎婿,這世上最難降的妖魔是什么测僵? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,157評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮谢翎,結(jié)果婚禮上捍靠,老公的妹妹穿的比我還像新娘沐旨。我一直安慰自己,他們只是感情好剂公,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布希俩。 她就那樣靜靜地躺著,像睡著了一般纲辽。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上璃搜,一...
    開(kāi)封第一講書(shū)人閱讀 51,125評(píng)論 1 297
  • 那天拖吼,我揣著相機(jī)與錄音,去河邊找鬼这吻。 笑死吊档,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的唾糯。 我是一名探鬼主播怠硼,決...
    沈念sama閱讀 40,028評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼移怯!你這毒婦竟也來(lái)了香璃?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 38,887評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤舟误,失蹤者是張志新(化名)和其女友劉穎葡秒,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體嵌溢,經(jīng)...
    沈念sama閱讀 45,310評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡眯牧,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了赖草。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片学少。...
    茶點(diǎn)故事閱讀 39,690評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖秧骑,靈堂內(nèi)的尸體忽然破棺而出版确,到底是詐尸還是另有隱情,我是刑警寧澤腿堤,帶...
    沈念sama閱讀 35,411評(píng)論 5 343
  • 正文 年R本政府宣布阀坏,位于F島的核電站,受9級(jí)特大地震影響笆檀,放射性物質(zhì)發(fā)生泄漏忌堂。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評(píng)論 3 325
  • 文/蒙蒙 一酗洒、第九天 我趴在偏房一處隱蔽的房頂上張望士修。 院中可真熱鬧枷遂,春花似錦、人聲如沸棋嘲。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)沸移。三九已至痪伦,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間雹锣,已是汗流浹背网沾。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,812評(píng)論 1 268
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蕊爵,地道東北人辉哥。 一個(gè)月前我還...
    沈念sama閱讀 47,693評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像攒射,于是被迫代替她去往敵國(guó)和親醋旦。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評(píng)論 2 353

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