# 视频截图,系统微博分享,截屏屏幕闪烁实现方法 iOS

> #import <AVFoundation/AVFoundation.h>
> #import <MediaPlayer/MediaPlayer.h> // 获取音量需要导入
> #import <AudioToolbox/AudioToolbox.h>// 将短音频注册到系统声音服务(SystemSoundService), 音效框架
> #import <Social/Social.h>// 本地新浪分享


 - (void)viewDidLoad{
     [super viewDidLoad];
     
      // 闪烁效果动画 view 层
    self.flashView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, HEIGHT, WIDTH)];
    self.flashView.backgroundColor = [UIColor whiteColor];
    [self  addSubview:self.flashView];
    [self.flashView setAlpha:0];
}



// 截图执行方法, 为了调出截图方法, 将方法单独写在外面, 由点击button调用,接口声明出去,调到 vc 中去执行摇一摇方法.
- (void)screenShotAction{

// 屏幕闪烁方法
[self.flashView setAlpha:1];
//开始动画
[UIView beginAnimations:@"flash screen" context:nil];
//动画时间
[UIView setAnimationDuration:0.3f];
//动画效果枚举值 淡入淡出动画
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
//将闪烁view的透明度变为 透明
[self.flashView setAlpha:0.0f];
//结束动画
[UIView commitAnimations];



/* indicates the current rate of playback; 0.0 means "stopped", 1.0 means "play at the natural rate of the current item" */
// 视频播放进度状态改为 0 ,防止截图时, 视频流媒体还在进行
self.moviePlayer.rate = 0;

// 视频暂停(光有暂停会出现截图现在但是往后推迟两秒的截图)
[self.moviePlayer pause];


NSURL* Url = [NSURL URLWithString:self.urlForPlayer];

// 获取视频当前进度时间
CGFloat current = CMTimeGetSeconds(self.moviePlayer.currentTime);
CMTime time = CMTimeMake(current,1);


//调用音效
[self playSoundEffect:@"shot.mp3"];

pragma mark -- 将类方法写入方法中, 由于类方法中不能有实例变量, 所以将类方法直接放入方法中

//视频资源
AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:Url  options:nil];
//视频资源截图工具
AVAssetImageGenerator *gen = [[AVAssetImageGenerator alloc] initWithAsset:asset];

asset = nil;
/** 注意:防止截图为反向 appliesPreferredTrackTransform这个属性,默认是false(Objective-C中为NO),只要将其设置为true,在进行截图就会发现,方向正常了。*/
gen.appliesPreferredTrackTransform = YES;

NSError *error  =nil;

//缩略图实际生成的时间(当前时间)
CMTime actualTime;

//获取time处的视频截图( 指定时间 )
CGImageRef image = [gen copyCGImageAtTime:time actualTime:&actualTime error:&error];

if (error) {
    NSLog(@"截取视频图片失败:%@",error.localizedDescription);
}

//显示当前时间
CMTimeShow(actualTime);

gen = nil;

//将CGImageref转换成UIImage
self.thumb =[[UIImage alloc] initWithCGImage:image];

//保存截图
//    UIImageWriteToSavedPhotosAlbum(self.thumb,nil, nil,nil);

/**
 *  注意: 最后必须要调用这个函数,否则会造成内存泄露
 *  ARC does not manage C-types, of which CGImage may be considered. You must release the ref manually when you are finished with CGImageRelease(image);
 */
CGImageRelease(image);

NSLog(@"视频截取成功");



// 获取响应者链,找到下层 vc  弹出截图 vc 添加照片
id object = [self nextResponder];

while (![object isKindOfClass:[SDP_PlayerViewController class]]) {
    object = [object nextResponder];
}

//获取播放器 vc 层
SDP_PlayerViewController *VCForPlayer = (SDP_PlayerViewController *)object;

NSLog(@"%@", VCForPlayer);

// 截图层 vc
self.screenShot = [[SDP_ScreeenShot alloc]init];

// 截取图片
UIImageView *imagefff =[[UIImageView alloc] initWithImage:self.thumb];
imagefff.frame = [UIScreen mainScreen].bounds;
imagefff.frame = CGRectMake(40, 20, [UIScreen mainScreen].bounds.size.width - 80, [UIScreen mainScreen].bounds.size.height - 80);

/** 截图图片尺寸/图片填充方法*/
imagefff.contentMode =  UIViewContentModeScaleAspectFill;
// 覆盖的部分被截取掉
imagefff.clipsToBounds  = YES;

//将图片放到 截图 VC
[self.screenShot.view addSubview:imagefff];

// 取消 button
UIButton *buttonForCancle = [UIButton buttonWithType:UIButtonTypeCustom];
[buttonForCancle setImage:[UIImage imageNamed:@"cancle"] forState:UIControlStateNormal];
[buttonForCancle addTarget:self action:@selector(BackAction:) forControlEvents:UIControlEventTouchUpInside];
buttonForCancle.frame = CGRectMake(WIDTH/3.3, HEIGHT - 60, 60, 60);
[self.screenShot.view addSubview:buttonForCancle];

// 分享 button


/**
 *   新浪
 */
self.buttonForShareSina = [UIButton buttonWithType:UIButtonTypeCustom];
[self.buttonForShareSina setImage:[UIImage imageNamed:@"sina"] forState:UIControlStateNormal];
[self.buttonForShareSina addTarget:self action:@selector(ShareSinaAction:) forControlEvents:UIControlEventTouchUpInside];
self.buttonForShareSina.frame = CGRectMake(WIDTH/2.2, HEIGHT - 60, 60, 60);
[self.screenShot.view addSubview:self.buttonForShareSina];

/**
 *   微信
 */
self.buttonForShareWeChat = [UIButton buttonWithType:UIButtonTypeCustom];
[self.buttonForShareWeChat setImage:[UIImage imageNamed:@"Wechat"] forState:UIControlStateNormal];
[self.buttonForShareWeChat addTarget:self action:@selector(shareAction:) forControlEvents:UIControlEventTouchUpInside];
self.buttonForShareWeChat.frame = CGRectMake(WIDTH/2.2, HEIGHT - 60, 60, 60);
[self.screenShot.view addSubview:self.buttonForShareWeChat];

/**
 *   朋友圈
 */

self.buttonForShareFriend = [UIButton buttonWithType:UIButtonTypeCustom];
[self.buttonForShareFriend setImage:[UIImage imageNamed:@"friend"] forState:UIControlStateNormal];
[self.buttonForShareFriend addTarget:self action:@selector(shareAction:) forControlEvents:UIControlEventTouchUpInside];
self.buttonForShareFriend.frame = CGRectMake(WIDTH/2.2, HEIGHT - 60, 60, 60);
[self.screenShot.view addSubview:self.buttonForShareFriend];


self.buttonForShareShot = [UIButton buttonWithType:UIButtonTypeCustom];
[self.buttonForShareShot setImage:[UIImage imageNamed:@"shotForShare"] forState:UIControlStateSelected];
[self.buttonForShareShot setImage:[UIImage imageNamed:@"shotForShare"] forState:UIControlStateNormal];
[self.buttonForShareShot addTarget:self action:@selector(shareAction:) forControlEvents:UIControlEventTouchUpInside];
self.buttonForShareShot.frame = CGRectMake(WIDTH/2.2, HEIGHT - 60, 60, 60);
[self.screenShot.view addSubview:self.buttonForShareShot];


// 确认保存
UIButton *buttonForSure = [UIButton buttonWithType:UIButtonTypeCustom];
[buttonForSure setImage:[UIImage imageNamed:@"shotForSure"] forState:UIControlStateNormal];
[buttonForSure addTarget:self action:@selector(SaveShot:) forControlEvents:UIControlEventTouchUpInside];
buttonForSure.frame = CGRectMake(WIDTH/1.65, HEIGHT - 60, 60, 60);
[self.screenShot.view addSubview:buttonForSure];


// 模态推出透明的 vc 

VCForPlayer.definesPresentationContext = YES; // VCForPlayer is presenting view controller
self.screenShot.view.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.5];
self.screenShot.modalPresentationStyle = UIModalPresentationOverCurrentContext;

//模态推出截图
[VCForPlayer presentViewController:self.screenShot animated:YES completion:^{
    
}];


}

pragma mark 取消截图

- (void)BackAction:(UIButton *)button{

[self.screenShot dismissViewControllerAnimated:YES completion:^{
    
    // 播放状态变为暂停, 播放键状态为暂停
   self.buttonForPlay.selected = YES;
    
}];
}

pragma mark 保存截图

- (void)SaveShot:(UIButton *)button{

//保存截图到相册
UIImageWriteToSavedPhotosAlbum(self.thumb,nil, nil,nil);
NSLog(@"视频截取成功");

[self.screenShot dismissViewControllerAnimated:YES completion:^{
    
    // 播放状态变为暂停, 播放键状态为暂停
    self.buttonForPlay.selected = YES;
}];

}

pragma mark 截图后分享的实现方法

- (void)shareAction:(UIButton *)button{

button.selected = !button.selected;

if (button.selected) {
    
   [UIView animateWithDuration:0.5 animations:^{
       // 微信
       self.buttonForShareWeChat.frame = CGRectMake(WIDTH/1.8, HEIGHT - 120, 60, 60);
   }];
    
    
    [UIView animateWithDuration:0.3 animations:^{
        // 新浪
        self.buttonForShareSina.frame = CGRectMake(WIDTH/2.8, HEIGHT - 120, 60, 60);
        
    }];
    
    [UIView animateWithDuration:0.4 animations:^{
        // 微信朋友圈
        self.buttonForShareFriend.frame = CGRectMake(WIDTH/2.2, HEIGHT - 160, 60, 60);
    }];
    

}else{
    
    [UIView animateWithDuration:0.3 animations:^{
        // 归到最开始
        self.buttonForShareWeChat.frame = CGRectMake(WIDTH/2.2, HEIGHT - 60, 60, 60);
        self.buttonForShareSina.frame = CGRectMake(WIDTH/2.2, HEIGHT - 60, 60, 60);
        self.buttonForShareFriend.frame = CGRectMake(WIDTH/2.2, HEIGHT - 60, 60, 60);
        
    }];
    
    
}

}

// 微博分享

- (void)ShareSinaAction:(UIButton *)button{

    // 点击微博分享后, 按键收回
    [UIView animateWithDuration:0.3 animations:^{
       
    // 归到最开始
    self.buttonForShareWeChat.frame = CGRectMake(WIDTH/2.2, HEIGHT - 60, 60, 60);
    self.buttonForShareSina.frame = CGRectMake(WIDTH/2.2, HEIGHT - 60, 60, 60);
    self.buttonForShareFriend.frame = CGRectMake(WIDTH/2.2, HEIGHT - 60, 60, 60);
    
}];


// 1.判断平台是否可用(系统没有集成,用户设置账号)
if (![SLComposeViewController isAvailableForServiceType:SLServiceTypeSinaWeibo]) {
    
    NSLog(@"设置界面设置自己的账号");
    
    NSURL *url = [NSURL URLWithString:@"prefs:root="];
    
    if ([[UIApplication sharedApplication] canOpenURL:url])
    {
        [[UIApplication sharedApplication] openURL:url];
    }
    
    return;
}

// 2.创建分享控制器
SLComposeViewController *composeVc = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeSinaWeibo];

// 视频主题 + 视频连接 + 视频描述(开眼提供了微博正好的字数)
NSString *strForText = [NSString stringWithFormat:@"[%@]:%@ %@", self.labelForMovieTitle.text,self.movieDescription, self.urlForPlayer ];


// 2.1.添加分享的文字 添加的为每个item的标题
[composeVc setInitialText:strForText];

// 2.2.添加分享的图片, item 的图片
[composeVc addImage:self.thumb];


// 3.弹出控制器进行分享
[self.screenShot presentViewController:composeVc animated:YES completion:nil];

// 4.设置监听发送结果
composeVc.completionHandler = ^(SLComposeViewControllerResult reulst) {
    if (reulst == SLComposeViewControllerResultDone) {
       
        NSLog(@"用户发送成功");

    } else {
        NSLog(@"用户发送失败");
    }
};
}

pragma mark -截图音效

/* 音效播放完成的回调函数,这个是C语言函数,第一个参数是音效ID,第二个是万能参数 */
void soundCompleteCallBack(SystemSoundID soundID, void *clientData){
NSLog(@"播放完成");
}

- (void)playSoundEffect:(NSString *)name {
//获取音效文件路径
NSString *filePath = [[NSBundle mainBundle] pathForResource:name ofType:nil];
//创建音效文件URL
NSURL *fileUrl = [NSURL URLWithString:filePath];
//音效声音的唯一标示ID
SystemSoundID soundID = 0;
//将音效加入到系统音效服务中,NSURL需要桥接成CFURLRef,会返回一个长整形ID,用来做音效的唯一标示
AudioServicesCreateSystemSoundID((__bridge CFURLRef)(fileUrl), &soundID);
//设置音效播放完成后的回调C语言函数
AudioServicesAddSystemSoundCompletion(soundID,NULL,NULL,soundCompleteCallBack,NULL);
//开始播放音效
AudioServicesPlaySystemSound(soundID);
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,684评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,143评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,214评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,788评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,796评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,665评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,027评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,679评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,346评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,664评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,766评论 1 331
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,412评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,015评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,974评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,073评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,501评论 2 343

推荐阅读更多精彩内容