使用GPUImage給視頻添加水印

- (void)addWaterMark {
    /* 使用GUPImage添加水印铣卡,原理上相當于添加一層濾鏡  */
    
    NSURL *videoURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"IMG_4400" ofType:@"m4v"]];
    _movieFile = [[GPUImageMovie alloc] initWithURL:videoURL];
//    _movieFile.runBenchmark = YES;
    _movieFile.playAtActualSpeed = NO;

    // 獲取視頻的size,從而確定水印的位置
    AVAsset *asset = [AVAsset assetWithURL:videoURL];
    CGSize size = CGSizeZero;
    NSArray *tracks = [asset tracksWithMediaType:AVMediaTypeVideo];
    if (tracks.count > 0) {
        AVAssetTrack *videoTrack = tracks.firstObject;
        size = CGSizeMake(videoTrack.naturalSize.width, videoTrack.naturalSize.height);
    }

    // 文字水印(同理可添加圖片)
    UILabel *label = [[UILabel alloc] init];
    label.text = @"@Ander";
    label.font = kFontFromPx(100);
    label.textColor = kColorWithRGB(0xFFFFFF);
    label.textAlignment = NSTextAlignmentCenter;
    [label sizeToFit];
    label.frame = CGRectMake(size.width - label.size.width - 20, size.height - label.size.height - 20, label.size.width, label.size.height);
    // 將水印放在一個跟視頻大小相等的View上
    UIView *subView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, size.width, size.height)];
    [subView addSubview:label];
    
    _uiElement = [[GPUImageUIElement alloc] initWithView:subView];
    _blendFilter = [[GPUImageNormalBlendFilter alloc] init];
    GPUImageFilter* progressFilter = [[GPUImageFilter alloc] init];
    
    // 注意URL不要出錯补箍,不然下面會崩潰
    NSString *pathToMovie = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/Movie.mp4"];
    unlink([pathToMovie UTF8String]);   // 刪除當前該路徑下的文件
    NSURL *movieURL = [NSURL fileURLWithPath:pathToMovie];
    
    _movieWriter = [[GPUImageMovieWriter alloc] initWithMovieURL:movieURL size:size];
    [progressFilter addTarget:_blendFilter];
    [_movieFile addTarget:progressFilter];
    [_uiElement addTarget:_blendFilter];
    
    _movieWriter.shouldPassthroughAudio = YES;
    // 判斷是否有音軌
    if ([asset tracksWithMediaType:AVMediaTypeAudio].count > 0){
        _movieFile.audioEncodingTarget = _movieWriter;
    } else {
        _movieFile.audioEncodingTarget = nil;
    }
    [_movieFile enableSynchronizedEncodingUsingMovieWriter:_movieWriter];
    [_blendFilter addTarget:_movieWriter];
    
    [_movieWriter startRecording];
    [_movieFile startProcessing];
    __weak typeof(self) weakSelf = self;
    //渲染
    [progressFilter setFrameProcessingCompletionBlock:^(GPUImageOutput *output, CMTime time) {
        dispatch_async(dispatch_get_main_queue(), ^{
            //水印可以移動
            CGRect frame = label.frame;
            frame.origin.x -= 1;
            frame.origin.y -= 1;
            label.frame = frame;
            //第5秒之后隱藏coverImageView2
            if (time.value/time.timescale>=5.0) {
                [label removeFromSuperview];
            }
        });
        // 這句必須有
        [weakSelf.uiElement update];
    }];

    [_movieWriter setCompletionBlock:^{
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            __strong typeof(self) strongSelf = weakSelf;
            [strongSelf.blendFilter removeTarget:strongSelf.movieWriter];
            [strongSelf.movieWriter finishRecording];
            //保存相冊
            __block PHObjectPlaceholder *placeholder;
            if ([PHPhotoLibrary authorizationStatus] == PHAuthorizationStatusAuthorized) {
                if (UIVideoAtPathIsCompatibleWithSavedPhotosAlbum(pathToMovie)) {
                    NSError *error;
                    [[PHPhotoLibrary sharedPhotoLibrary] performChangesAndWait:^{
                        PHAssetChangeRequest* createAssetRequest = [PHAssetChangeRequest creationRequestForAssetFromVideoAtFileURL:movieURL];
                        placeholder = [createAssetRequest placeholderForCreatedAsset];
                    } error:&error];
                    if (error) {
                        kShowPopTip(nil, error.description, nil);
                    }else {
                        kShowPopTip(nil, @"視頻已保存到相冊", nil);
                    }
                }
            }
        });
    }];
}

參考文章:
http://www.hudongdong.com/ios/546.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子填抬,更是在濱河造成了極大的恐慌,老刑警劉巖隧期,帶你破解...
    沈念sama閱讀 217,406評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件痴奏,死亡現(xiàn)場離奇詭異,居然都是意外死亡厌秒,警方通過查閱死者的電腦和手機读拆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評論 3 393
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來鸵闪,“玉大人檐晕,你說我怎么就攤上這事。” “怎么了辟灰?”我有些...
    開封第一講書人閱讀 163,711評論 0 353
  • 文/不壞的土叔 我叫張陵个榕,是天一觀的道長。 經(jīng)常有香客問我芥喇,道長西采,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,380評論 1 293
  • 正文 為了忘掉前任继控,我火速辦了婚禮绩脆,結(jié)果婚禮上涛舍,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好禀倔,可當我...
    茶點故事閱讀 67,432評論 6 392
  • 文/花漫 我一把揭開白布北启。 她就那樣靜靜地躺著袱箱,像睡著了一般登馒。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上囚枪,一...
    開封第一講書人閱讀 51,301評論 1 301
  • 那天派诬,我揣著相機與錄音,去河邊找鬼链沼。 笑死默赂,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的忆植。 我是一名探鬼主播放可,決...
    沈念sama閱讀 40,145評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼谒臼,長吁一口氣:“原來是場噩夢啊……” “哼朝刊!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起蜈缤,我...
    開封第一講書人閱讀 39,008評論 0 276
  • 序言:老撾萬榮一對情侶失蹤拾氓,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后底哥,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體咙鞍,經(jīng)...
    沈念sama閱讀 45,443評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,649評論 3 334
  • 正文 我和宋清朗相戀三年趾徽,在試婚紗的時候發(fā)現(xiàn)自己被綠了续滋。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,795評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡孵奶,死狀恐怖疲酌,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤朗恳,帶...
    沈念sama閱讀 35,501評論 5 345
  • 正文 年R本政府宣布湿颅,位于F島的核電站,受9級特大地震影響粥诫,放射性物質(zhì)發(fā)生泄漏油航。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,119評論 3 328
  • 文/蒙蒙 一怀浆、第九天 我趴在偏房一處隱蔽的房頂上張望谊囚。 院中可真熱鬧,春花似錦揉稚、人聲如沸秒啦。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽余境。三九已至,卻和暖如春灌诅,著一層夾襖步出監(jiān)牢的瞬間芳来,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評論 1 269
  • 我被黑心中介騙來泰國打工猜拾, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留即舌,地道東北人。 一個月前我還...
    沈念sama閱讀 47,899評論 2 370
  • 正文 我出身青樓挎袜,卻偏偏與公主長得像顽聂,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子盯仪,可洞房花燭夜當晚...
    茶點故事閱讀 44,724評論 2 354