阅读 44 SEO

iOS视频添加水印两种方式(不用到第三方框架)

iOS视频添加水印两种方式(不用到第三方框架)

1、视频加水印,并保存到沙盒当中

//原视频sureasset,有外界传进来

 AVURLAsset *asset = (AVURLAsset *)[self addPhotoTitleWithAsset:sureasset][0];

    AVMutableVideoComposition *mainCompositionInst = [self addPhotoTitleWithAsset:sureasset][1];

    sureasset = asset;

    

    AVAssetExportSession *session = [[AVAssetExportSession alloc] initWithAsset: sureasset presetName:AVAssetExportPresetMediumQuality];

    NSString *failPath = [self getVideosPath:@"localVideo"];//获取路径

    NSURL *filUrl = [NSURL fileURLWithPath:failPath];

    session.outputURL = filUrl;//视频输出地址

    session.outputFileType = AVFileTypeMPEG4;//AVFileTypeQuickTimeMovie;//AVFileTypeMPEG4;

    

    // 这个一般设置为yes(指示输出文件应针对网络使用进行优化,例如QuickTime电影文件应支持“快速启动”)

    session.shouldOptimizeForNetworkUse = YES;

    // 文件的最大多大的设置

    session.fileLengthLimit = 30 * 1024 * 1024;

    

    session.shouldOptimizeForNetworkUse = YES;

    session.videoComposition = mainCompositionInst;

    

    [session exportAsynchronouslyWithCompletionHandler:^(void){

        dispatch_async(dispatch_get_main_queue(), ^{

            //视频导入成功

            //failPath为本地视频地址

            completeBlock(failPath,YES);

        });

    }];

    

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

//获取路径

- (NSString *)getVideosPath:(NSString *)videoName{

    NSString *documents = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)[0];

    documents = [documents stringByAppendingPathComponent:@"CCTV5"];

    documents = [self action_addFiles:documents];//判断文件是否存在

    NSString *failPath = [documents stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.mp4",videoName]];

    return failPath;

}

1

2

3

4

5

6

7

8

#pragma mark- 视频加水印

//添加水印

-(NSArray *)addPhotoTitleWithAsset:(AVAsset *)videoAsset

{

    //1 创建AVAsset实例

    //AVURLAsset*videoAsset = [AVURLAsset assetWithURL:[NSURL fileURLWithPath:path]];

    

    AVMutableComposition *mixComposition = [[AVMutableComposition alloc] init];

    

    

    //3 视频通道

    AVMutableCompositionTrack *videoTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo

                                                                        preferredTrackID:kCMPersistentTrackID_Invalid];

    [videoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, videoAsset.duration)

                        ofTrack:[[videoAsset tracksWithMediaType:AVMediaTypeVideo] firstObject]

                         atTime:kCMTimeZero error:nil];

    

    

    //2 音频通道

    AVMutableCompositionTrack *audioTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeAudio

                                                                        preferredTrackID:kCMPersistentTrackID_Invalid];

    [audioTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, videoAsset.duration)

                        ofTrack:[[videoAsset tracksWithMediaType:AVMediaTypeAudio] firstObject]

                         atTime:kCMTimeZero error:nil];

    

    //3.1 AVMutableVideoCompositionInstruction 视频轨道中的一个视频,可以缩放、旋转等

    AVMutableVideoCompositionInstruction *mainInstruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];

    mainInstruction.timeRange = CMTimeRangeMake(kCMTimeZero, videoAsset.duration);

    

    // 3.2 AVMutableVideoCompositionLayerInstruction 一个视频轨道,包含了这个轨道上的所有视频素材

    AVMutableVideoCompositionLayerInstruction *videolayerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:videoTrack];

    

    [videolayerInstruction setOpacity:0.0 atTime:videoAsset.duration];

    

    // 3.3 - Add instructions

    mainInstruction.layerInstructions = [NSArray arrayWithObjects:videolayerInstruction,nil];

    

    //AVMutableVideoComposition:管理所有视频轨道,水印添加就在这上面

    AVMutableVideoComposition *mainCompositionInst = [AVMutableVideoComposition videoComposition];

    

    AVAssetTrack *videoAssetTrack = [[videoAsset tracksWithMediaType:AVMediaTypeVideo] firstObject];

    CGSize naturalSize = videoAssetTrack.naturalSize;

    //防崩溃处理,这个width可能为空,按比例给他值

    if (naturalSize.width == 0) {

        CGFloat a = (1280.f / 720);

        naturalSize.width =  a * naturalSize.height;

    }

    

    float renderWidth, renderHeight;

    renderWidth = naturalSize.width;

    renderHeight = naturalSize.height;

    mainCompositionInst.renderSize = CGSizeMake(renderWidth, renderHeight);

    mainCompositionInst.instructions = [NSArray arrayWithObject:mainInstruction];

    mainCompositionInst.frameDuration = CMTimeMake(1, 30);

    

    

    [self applyVideoEffectsToComposition:mainCompositionInst size:naturalSize];

 

    NSArray *arrar = [NSArray arrayWithObjects:mixComposition,mainCompositionInst, nil];

    return arrar;;

}

/**

 设置水印及其对应视频的位置

 

 @param composition 视频的结构

 @param size 视频的尺寸

 */

- (void)applyVideoEffectsToComposition:(AVMutableVideoComposition *)composition size:(CGSize)size

{

    // 文字

    CATextLayer *subtitle1Text = [[CATextLayer alloc] init];

    //    [subtitle1Text setFont:@"Helvetica-Bold"];

    [subtitle1Text setFontSize:36];

    [subtitle1Text setFrame:CGRectMake(10, size.height-10-230, size.width, 100)];

    [subtitle1Text setString:@"央视体育5 水印"];

    //    [subtitle1Text setAlignmentMode:kCAAlignmentCenter];

    [subtitle1Text setForegroundColor:[[UIColor whiteColor] CGColor]];

    

    //图片

    CALayer*picLayer = [CALayer layer];

    

    //picLayer.contents = (id)[UIImage imageNamed:@"CTVITTRIMSource.bundle/QQ"].CGImage; //本地图片

    picLayer.contents = (id)self.videoWaterMarkImage.CGImage; //本地图片2

    //NSString *imageUrl = @"http://p1.img.cctvpic.com/photoAlbum/templet/special/PAGEQ1KSin2j2U5FERGWHp1h160415/ELMTnGlKHUJZi7lz19PEnqhM160415_1460715755.png";

    //picLayer.contents = (id)[self getImageFromURL:imageUrl].CGImage; //远程图片

    CGFloat width = 63;

    CGFloat leftMargin = 16 * [self scaleSizeWithHeight:size.height];

    CGFloat topMargin = 20 * [self scaleSizeWithHeight:size.height];

    if (self.videoWaterMarkPlace == WaterMarkTopLeft) {

        picLayer.frame = CGRectMake(leftMargin, size.height-topMargin-[self scaleSizeWithHeight:size.height]*50, [self scaleSizeWithHeight:size.height]*width, [self scaleSizeWithHeight:size.height]*width);

    }

    if (self.videoWaterMarkPlace == WaterMarkBottomLeft) {

        picLayer.frame = CGRectMake(leftMargin, 20, [self scaleSizeWithHeight:size.height]*50, [self scaleSizeWithHeight:size.height]*50);

    }

    if (self.videoWaterMarkPlace == WaterMarkTopRight) {

        picLayer.frame = CGRectMake(size.width - 20 - [self scaleSizeWithHeight:size.height]*50, size.height-20-[self scaleSizeWithHeight:size.height]*50, [self scaleSizeWithHeight:size.height]*50, [self scaleSizeWithHeight:size.height]*50);

    }

    if (self.videoWaterMarkPlace == WaterMarkBottomRight) {

        picLayer.frame = CGRectMake(size.width - 20 - [self scaleSizeWithHeight:size.height]*50, 20, [self scaleSizeWithHeight:size.height]*50, [self scaleSizeWithHeight:size.height]*50);

        

    }

    

    // 2 - The usual overlay

    CALayer *overlayLayer = [CALayer layer];

    [overlayLayer addSublayer:picLayer];

    //    [overlayLayer addSublayer:subtitle1Text];

    overlayLayer.frame = CGRectMake(0, 0, size.width, size.height);

    [overlayLayer setMasksToBounds:YES];

    

    CALayer *parentLayer = [CALayer layer];

    CALayer *videoLayer = [CALayer layer];

    parentLayer.frame = CGRectMake(0, 0, size.width, size.height);

    videoLayer.frame = CGRectMake(0, 0, size.width, size.height);

    [parentLayer addSublayer:videoLayer];

    [parentLayer addSublayer:overlayLayer];

    

    composition.animationTool = [AVVideoCompositionCoreAnimationTool

                                 videoCompositionCoreAnimationToolWithPostProcessingAsVideoLayer:videoLayer inLayer:parentLayer];

    

}


//ios 从网络上获取图片

-(UIImage *) getImageFromURL:(NSString *)fileURL {

    //https://vod.cctv.cn/cctvsports/cctv5/img/advertisingImage.jpg

    NSLog(@"执行图片下载函数");

    

    UIImage * result;

    

    NSData * data = [NSData dataWithContentsOfURL:[NSURL URLWithString:fileURL]];

    

    result = [UIImage imageWithData:data];

    

    return result;

    

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

2、另一种实现方式

    //    [self applyVideoEffectsToComposition:mainCompositionInst size:naturalSize];

    

    CIFilter *watermarkFilter = [CIFilter filterWithName:@"CISourceOverCompositing"];

    

    mainCompositionInst = [AVMutableVideoComposition videoCompositionWithAsset:videoAsset applyingCIFiltersWithHandler:^(AVAsynchronousCIImageFilteringRequest * _Nonnull request) {

        

        CIImage *watermarkImage  =  [[CIImage alloc] initWithCGImage:self.videoWaterMarkImage.CGImage];

        

        CIImage *source = request.sourceImage;

        

        [watermarkFilter setValue:source forKey:kCIInputBackgroundImageKey];

        

        [watermarkFilter setValue:[watermarkImage imageByApplyingTransform:CGAffineTransformMakeScale(0.5, 0.5)] forKey:kCIInputImageKey];

        

        

        

        [watermarkFilter setValue:[watermarkImage imageByApplyingTransform:CGAffineTransformMakeTranslation(14, source.extent.size.height - 14 - watermarkImage.extent.size.height)] forKey:kCIInputImageKey];

        [request finishWithImage:watermarkFilter.outputImage context:nil];

        

    }];

    

    

    //       //    // 4 - 输出路径

————————————————

版权声明:本文为CSDN博主「黑码哥」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/liyunxiangrxm/article/details/106687545


文章分类
后端
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 gxwowoo@163.com 举报,一经查实,本站将立刻删除。
相关推荐