美文网首页iOS音视频开发iOS视频开发直播
iOS:抖音短视频生成webp动图客户端解决方案

iOS:抖音短视频生成webp动图客户端解决方案

作者: Yi小祥 | 来源:发表于2018-04-02 18:23 被阅读1154次

    前言


    最近要求做一个类似抖音将短视频生成动图在列表进行展示的需求,生成动图最大的好处是用户在列表能够最直观地预览到短视频的大致内容,虽然这个是个用户体验的加分项,但是如果我们不能处理好图片占用空间及清晰度问题,也会带来副作用。

    那么,我们该如何权衡呢?

    Gif or Webp?

    要想使用动图并且图片足够小,当然是用Webp了,图1是gif和webp的对比,可见webp节省了不少空间!这里有篇介绍Webp的经典文章,有兴趣的朋友可以了解下:浓缩的精华!从零开始带你认识最新的图片格式WEBP

    图1

    截取视频帧

    截取视频一帧关键代码如下:

    AVAssetImageGenerator *generator = [[AVAssetImageGenerator alloc] initWithAsset:asset];

    generator.appliesPreferredTrackTransform = YES;

    //下面两个值设为0表示精确取帧,否则系统会有优化取出来的帧时间间隔不对等

    generator.requestedTimeToleranceAfter = kCMTimeZero;

    generator.requestedTimeToleranceBefore = kCMTimeZero;

    生成Webp

    这里推荐一个功能强大的iOS 图像框架:YYImage

    使用YYImageEncoder可以很方便的生成gif或webp动图,实例代码:

    YYImageEncoder *gifEncoder = [[YYImageEncoder alloc] initWithType:YYImageTypeWebP];

    gifEncoder.loopCount=0;

    gifEncoder.quality=0.8;

    [gifEncoder addImage:img duration:0.1];

    [gifEncoder encodeToFile:filePath];

    至此,2个关键技术点讲完了,不妨试试截取几帧生成一个webp试试手......

    当你惊喜的发现图片已经生成的同时,也会惊讶的发现图片占用空间依然很大啊。

    继续优化

    要想尽可能的优化图片空间,只有从两个方面入手:

    1、尽可能减少图片帧数

    2、尽可能压缩图片

    针对第一点,以及参考抖音的效果,我的方案如下:

    总共截取9帧图片,前5帧从视频的0.5秒开始,每间隔0.1秒截取一帧;然后倒序再截取4帧,从而形成倒序播放的效果。

    针对第二点,首先对图片大小按比例进行裁剪,以最大边长不超过480为依据进行等比压缩,然后设置0.8的有损压缩。

    最终方案:

    - (void)saveToWebpByVideoPath:(NSURL*)videoUrl webpFilePath:(NSString*)webpFilePath{

        YYImageEncoder *gifEncoder = [[YYImageEncoder alloc] initWithType:YYImageTypeWebP];

        gifEncoder.loopCount=0;

        gifEncoder.quality=0.8;

        AVURLAsset*asset = [[AVURLAssetalloc]initWithURL:videoUrloptions:nil];

        int64_t scale = asset.duration.timescale;

        AVAssetImageGenerator *generator = [[AVAssetImageGenerator alloc] initWithAsset:asset];

        generator.appliesPreferredTrackTransform = YES;

        //下面两个值设为0表示精确取帧,否则系统会有优化取出来的帧时间间隔不对等

        generator.requestedTimeToleranceAfter = kCMTimeZero;

        generator.requestedTimeToleranceBefore = kCMTimeZero;

        for(inti =0; i <=4; i++) {

            CGFloatstarttime = i*0.1+0.5;

            CMTimetime =CMTimeMakeWithSeconds(starttime, (int)scale);

            NSError*error =nil;

            CMTimeactualTime;

            CGImageRefimage = [generatorcopyCGImageAtTime:timeactualTime:&actualTimeerror:&error];

            UIImage* img = [UIImageimageWithCGImage:image];

            img = [selfresizeToMaxHeight:480img:img];

            [gifEncoderaddImage:imgduration:0.1];

            CGImageRelease(image);

        }

        for(inti=3; i>=0; i--) {

            CGFloatstarttime = i*0.1+0.5;

            CMTimetime =CMTimeMakeWithSeconds(starttime, (int)scale);

            NSError*error =nil;

            CMTimeactualTime;

            CGImageRefimage = [generatorcopyCGImageAtTime:timeactualTime:&actualTimeerror:&error];

            UIImage* img = [UIImageimageWithCGImage:image];

            img = [selfresizeToMaxHeight:480img:img];

            [gifEncoderaddImage:imgduration:0.1];

            CGImageRelease(image);

        }

        [gifEncoderencodeToFile:webpFilePath];

        NSLog(@"生成webp成功!");

    }

    - (UIImage*)resizeToMaxHeight:(CGFloat)height img:(UIImage*)img{

        if(img.size.width

            if(img.size.height>height) {

                CGSizenewSize =CGSizeMake(height*1.0*img.size.width/img.size.height, height);

                img = [imgyy_imageByResizeToSize:newSize contentMode:UIViewContentModeScaleToFill];

            }

        }

        else{

            if(img.size.width>height) {

                CGSizenewSize =CGSizeMake(height,img.size.height*height*1.0/img.size.width);

                img = [imgyy_imageByResizeToSize:newSize contentMode:UIViewContentModeScaleToFill];

            }

        }

        returnimg;

    }

    本文为作者原创,转载请注明出处,如果你觉得这篇文章对你有帮助或启发,欢迎❤️或送小礼物

    补充:Demo请戳这里

    相关文章

      网友评论

      • 倾城何处不暖阳:你好,好像Safari不支持webp 格式的图片。 我看文章里有损的gif 图的大小 我可以接受, 那我把图片类型改成gif 的应该也可以吧?YYImageTypeWebP 改成YYImageTypeGif
        Yi小祥:@倾城何处不暖阳 推荐使用YYImage,之前用过SDWebImage,列表gif很多的情况下会卡顿,换成YYImage后完美解决
        倾城何处不暖阳:@Yi小祥 好的, 谢谢, 请问现在展示gif图 性能较好的第三方框架是哪个? 是sdwebimage4.0 里用的flanimateimage 吗
        Yi小祥:文章只提了webp,当你掌握了原理就可以举一反三,换成gif当然也是可以的
      • 巧克力色可可:博主你好,这个demo下下来 pod install 怎么报错 跑不起来
        Yi小祥:@巧克力色可可 :+1:
        巧克力色可可:@Yi小祥 pod install报错 不过我已经根据你简书里的代码完成这个需求了
        Yi小祥:@巧克力色可可 报的什么错,pod install报错还是编译报错呢
      • shareInstance:网络视频的URL能实现吗
        shareInstance:@Yi小祥 厉害了,刚才忘记开运行HTTP了,打开果然可以。:+1:
        Yi小祥:调用saveToWebpByVideoPath传网络URL
        Yi小祥:可以的,不妨在提供的Demo中自己稍加改动就能验证你的问题。
      • 阿古斯年:你好,能提供一下demo吗,我自己测试的时候不成功..log打印如下:CMTimeMakeWithSeconds(0.500 seconds, timescale 1): warning: error of -0.500 introduced due to very low timescale
        视频放在工程里面可以的吗,还是要保存到沙盒里面,但是两种路径我都传过了,截取的图片依然是空的
        阿古斯年:@Yi小祥 好的,谢谢:pray:
        Yi小祥:等我传个Demo
        Yi小祥:视频放在工程和沙盒都可以,只要能访问到这个视频

      本文标题:iOS:抖音短视频生成webp动图客户端解决方案

      本文链接:https://www.haomeiwen.com/subject/vpsxhftx.html