back to top
1 C
New York
금요일, 12월 27, 2024

Buy now

워드프레스에서 움짤 gif 변환(GIF MP4 변환) 자동 구현 방법

GIF 움짤 용량이 상대적으로 크기 때문에 움짤 용량을 줄이기 위해 GIF MP4 변환하는 움짤 gif 변환을 자동으로 할 수 있는 방법을 연구, 테스트해 보고 그 방법을 정리해 공유해 봅니다.

원래는 webp 변환처럼 nginx 웹서버 기능을 활용하는 방법을 시도했지만, img 파일과 동영상 파일의 차이로 인해서 생각보다 복잡해 젔기 때문에 이를 포기하고 편리님이 제공한 간단한 플러그인을 적용하는 것을 정리했습니다.

테스트에 사용한 움짤 gif 이미지

우선 이 테스트에 사용된 GIF 움짤은 요즘 성가를 높이고 있는 블랙빙크의 리사의 아름다움 미소가 돋보이는 움짤 몇가지를 골라 보았습니다.

이 움짤 이미지들은 구글에서 가져온 것이라 지적재산권 문제를 확인해 보고 문제가 된다면 지우도록 하겠습니다.

GIF 움짤 중에서 화질이 좋은 것으로 골랐는데 아무래도 용량 문제가 있다보니 이미지 사이즈가 작은 파일들이 대부분이기는 합니다.

  • GIF 움짤 용량 1.5MB, 움짤 사이즈는 498×354
  • mp4 동영상으로 전환 시 154k로 거의 10% 수준으로 줄어 듬

  • GIF 움짤 용량 8MB, 움짤 사이즈는 498×498
  • mp4 동영상으로 전환 시 423k로 거의 50% 수준으로 줄어 듬

  • GIF 움짤 용량 2.6MB, 움짤 사이즈는 280×420
  • mp4 동영상으로 전환 시 190k로 거의 7% 수준으로 줄어 듬

움짤 gif 동영상 변환 프로그램 설치

먼저 gif mp4 변환이 가능한 동영상 변환 프로그램을 설치합니다. 인터넷을 검색해 보면 금방 알 수 있겠지만 공개용 프로그램으로 FFmpeg을 가장 많이 사용하는 것 같습니다.

우분투 20.04에서 설치하는 방법은 아래와 같습니다.

다행히도 우분투 20.04는 별다를 컴파일없이 바로 apt 명령으로 설치할 수 있네요. 아래 명령 사용하면 매우 단순하게 설치할 수 있습니다. 당연히 먼저 업데이트를 해서 최신 상태로 만들어 놓고 프로그램을 설치합니다.

sudo apt update
sudo apt install ffmpegCode language: PHP (php)

이것으로 설치가 끝났다. 그래도 뭐가 미진하니 설치한 버전 정도는 확인해 보시죠.

ffmpeg -versionCode language: PHP (php)

그러면 다음과 같은 메세지를 만날 수 있습니다.

ffmpeg version 4.2.4-1ubuntu0.1 Copyright (c) 2000-2020 the FFmpeg developers
built with gcc 9 (Ubuntu 9.3.0-10ubuntu2)
configuration: --prefix=/usr --extra-version=1ubuntu0.1 --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --arch=amd64 --enable-gpl --disable-stripping --enable-avresample --disable-filter=resample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libaom --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libcodec2 --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libjack --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librsvg --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzmq --enable-libzvbi --enable-lv2 --enable-omx --enable-openal --enable-opencl --enable-opengl --enable-sdl2 --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-nvenc --enable-chromaprint --enable-frei0r --enable-libx264 --enable-shared
libavutil      56. 31.100 / 56. 31.100
libavcodec     58. 54.100 / 58. 54.100
libavformat    58. 29.100 / 58. 29.100
libavdevice    58.  8.100 / 58.  8.100
libavfilter     7. 57.100 /  7. 57.100
libavresample   4.  0.  0 /  4.  0.  0
libswscale      5.  5.100 /  5.  5.100
libswresample   3.  5.100 /  3.  5.100
libpostproc    55.  5.100 / 55.  5.100
Code language: PHP (php)

[참] gif를 대체할 동영상 포맷 소개

움직이는 에니메이션 파일인 gif를 대체하는 동영상을 크게 세가지가 있습니다. mp4와 WebM 그리고 Ogg 파일 포맷이 그것들인데요.

gif는 1987년도에 컴퓨서브(CompServe)사에서 개발한 무손실 압축 이미지 포맷입니다. 무손실 압축에서 읽을 수 있다시피 상대적으로 용량이 크고, 색상 표현이 최대 256컬러만 지원하기 때문에 색 왜곡현상이 발생합니다. 그리고 프레임이 늘어날 수록 급격한 용량 증가가 발생합니다.

그렇지만 가장 오랜된 포맷인만큼 지원하지 않는 기기나 브라우저가 없기 때문에 그만큼 많은 사용자를 확보하고 있습니다.

이를 대체하기 위한 mp4와 같은 동영상 포맷은 html5가 등장하면서 <video> 태그가 추가되면서 별도의 설정없이 이러한 파일 포맷을 지원하는 브라우저가 점점 늘고 있습니다.

가장 많은 브라우저가 지원하는 mp4

위에서 정리한 세가지 포맷 중에서 mp4는 점점 더 많은 브라우저가 지원하면서 98%에 가까운 브라우저가 지원하고 있습니다.

전 세계적으로 도대체 얼마나 많은 브라우저가 이 mp4를 지원할까 살펴보니 98% 정도는 지원하네요. 대부분 지원한다고 봐야 할 듯 합니다.

mp4를 지원하는 브라우저 리스트, 98% 브라우저가 mp4를 지원
mp4를 지원하는 브라우저 리스트, 98% 브라우저가 mp4를 지원

mp4보다 성능이 좋은 WebM 포맷

위에서 이야기한 mp4보다 WebM 비디오 포맷이 더 압축율이 좋다고 합니다. 아쉽게도 이 비디오 포맷을 지원하는 브라우저는 96%정도로 조금 낮네요.

이 파일 포맷은 구글에서 만들었기 때문에 스티브잡스가 이끄는 애플은 오랬동안 이 포맷 지원을 거부해 왔습니다. 최근에는 제한적으로 지원하기 시작했죠.

아래 이미지에서 보는 것처럼 전 세계적으로 95.5% 지원한다고 하지만, 애플 계열은 부분적으로만 지원하기 때문에 완전한 96%라고 하기는 애매합니다.

더구나 우리나라에서 많이 사용하는 IE지원을 하디 않기 때문에 실제적으로는 70%~80%대 브라우저 지원율로 봐야 할 듯합니다.

webM 비디오 포맷을 지원하는 브라우저 리스트, 96% 브라우저가 webM을 지원
webM 비디오 포맷을 지원하는 브라우저 리스트, 96% 브라우저가 webM을 지원

가장 효울이 높고 오픈 소스인 Ogg

그리고 요즘 새롭게 등장하는 ogg 비디오 포맷은 78% 정도 지원하고 있습니다.

이 포맷은 가장 완전한 오픈소스라 지적재산권과 관련이 없고 성능도 뛰어납니다. 다만 브라우저 지원율이 상대적으로 매우 낮습니다.

자동으로 GIF를 mp4나 WebM으로 변환 재생하는 플러그인

원래는 Nginx에서 자동으로 변환하는 방법을 생각하려 했는데요. 앞에서 설명한대로 몇가지 이슈가 있어서 매우 간단한 플러그인 소개로 대체하겠습니다.

여기서 소개할 플러그인은 편리님이 소개한 방법입니다.

워드프레스 애니메이션 gif 파일을 mp4로 변환하여 출력하기

gif파일을 mp4 및 WebM 파일로 변경 코드

아래 코드를 functions.php 파일로 저장합니다.

<?php

// https://www.php.net/manual/en/function.imagecreatefromgif.php#104473
function isAnimatedGIF($gif) {
    if(!($fh = @fopen($gif, 'rb')))
        return false;

    $count = 0;
    //an animated gif contains multiple "frames", with each frame having a
    //header made up of:
    // * a static 4-byte sequence (\x00\x21\xF9\x04)
    // * 4 variable bytes
    // * a static 2-byte sequence (\x00\x2C) (some variants may use \x00\x21 ?)

    // We read through the file til we reach the end of the file, or we've found
    // at least 2 frame headers
    while(!feof($fh) && $count < 2) {
        $chunk = fread($fh, 1024 * 100); //read 100kb at a time
        $count += preg_match_all('#\x00\x21\xF9\x04.{4}\x00(\x2C|\x21)#s', $chunk, $matches);
    }

    fclose($fh);

    return $count > 1;
}

function convert_gif2mp4($content)
{
    $images = array();

    $upload_info = wp_upload_dir();
    $upload_dir = $upload_info['basedir'];
    $upload_url = $upload_info['baseurl'];

    $pattern = '#<img[^>]*src=[\'"]?(.+\.gif)[\'"]?[^>]*>#i';

    preg_match_all($pattern, $content, $matches);

    $count = count($matches[1]);
    $urls  = array();

    if ( $count > 0 ) {
        for ( $i=0; $i<$count; $i++ ) {
            $url  = $matches[1][$i];
            $url2 = preg_replace('#^https?:#i', '', $url);

            if(in_array($url2, $urls))
                continue;

            $urls[] = $url;

            // 로컬 파일인지 체크
            if(strpos( $url, $upload_url ) === false)
                continue;

            // 이미지 경로 설정
            $rel_path = str_replace( $upload_url, '', $url);
            $img_file = $upload_dir . $rel_path;

            // gif 파일인지 체크
            if( !is_file($img_file))
                continue;

            $size = @getimagesize($img_file);
            if($size[2] != 1)
                continue;

            // 애니메이션 gif 체크
            if (!isAnimatedGIF($img_file))
                continue;

            // mp4 파일 생성
            $pinfo = pathinfo($img_file);

            $mp4 = $pinfo['dirname'].'/'.$pinfo['filename'].'.mp4';
            $webm = $pinfo['dirname'].'/'.$pinfo['filename'].'.webm';
            $poster = $pinfo['dirname'].'/poster_'.$pinfo['filename'].'.jpg';

            if (is_writable($pinfo['dirname']) && !is_file($mp4)) {
                try {
                    $poster = $pinfo['dirname'].'/poster_'.$pinfo['filename'].'.jpg';
                    $image = @imagecreatefromgif($img_file);

                    imagejpeg($image, $poster, 90);

                    @exec('ffmpeg -i '.escapeshellcmd(preg_replace('/[^0-9A-Za-z_\-\.\\\\\/]/i', '', $img_file)).' -vf "scale=trunc(iw/2)*2:trunc(ih/2)*2" -c:v libx264 -pix_fmt yuv420p -movflags +faststart  '.escapeshellcmd(preg_replace('/[^0-9A-Za-z_\-\.\\\\\/]/i', '', $mp4)));

                    @exec('ffmpeg -i '.escapeshellcmd(preg_replace('/[^0-9A-Za-z_\-\.\\\\\/]/i', '', $img_file)).' -c vp9 -b:v 0 -crf 41  '.escapeshellcmd(preg_replace('/[^0-9A-Za-z_\-\.\\\\\/]/i', '', $webm)));
                } catch(Exception $e) {
                    continue;
                }
            }

            if (is_file($mp4)) {
                $video = '<video poster="'.str_replace($upload_dir, $upload_url, $poster).'" autoplay="autoplay" loop="loop" preload="auto" playsinline webkit-playsinline muted>';
                if (is_file($webm))
                    $video .= '<source src="'.str_replace($upload_dir, $upload_url, $webm).'" type="video/webm">';
                $video .= '<source src="'.str_replace($upload_dir, $upload_url, $mp4).'" type="video/mp4">';
                $video .= '</video>';

                $content = str_replace($matches[0][$i], $video, $content);
            }
        }
    }

    return $content;
}Code language: PHP (php)

워드프레스 플러그인 실행 파일

워드프레스에서 이 플러그인을 실행시키는 파일을 gif2mp4.php 파일로 저장합니다.

<?php

/**
 * @package Convert GIF to MP4 in Post
 * @version 1.0.0
 */
/*
Plugin Name: Convert GIF to MP4 in Post
Plugin URI: https://ncube.net/
Description: This plugin animated gif to mp4 using ffmpeg in post.
Author: chicpro
Version: 1.0.0
Author URI: https://ncube.net/
*/

require ( plugin_dir_path( __FILE__ ) . '/functions.php' );

add_filter ('the_content', 'convert_gif2mp4', 100);Code language: PHP (php)

워드프레스 플러그인 폴더 만들기

위에서 만든 워드프레스용 두개 파일을 워드프레스 플러그인 폴더에 gif2mp4와 같은 적절한 이름의 폴더를 만들고 여기에 이 두 파일을 복사합니다.

그리고 이 플러그인을 활성화 시킵니다.

참고

워드프레스 이미지 설정 최적화 방법

무료로 구축하는 이미지 최적화 자동화 시스템

서버에서 PNG 이미지 최적화로 사이트 속도 개선 방법

서버에서 JPEG 이미지 최적화로 사이트 속도 개선 방법

NGINX에서 최고의 이미지 압축 포맷 WebP 적용 방법

워드프레스 이미지 최적화에 필수적인 ImageMagick 설치 방법

spot_img

Latest articles

Related articles

spot_img