Skip to content

CHICPRO

  • Life Log
  • Cycling Log
  • Photo Log
    • Portrait
    • Landscape
    • Flower
    • Etc
  • Coding Log
  • Information

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

2020-08-14 by 편리

최근에 애니메이션 gif 파일을 mp4로 변경해서 출력하는 게 유행(?)이라고 할까? 포스팅 때 애니메이션 gif 파일을 첨부하지는 않기 때문에 굳이 관심을 가져야 할 이유가 없었는데.. 오늘은 왠지 한번 해볼까? 하는 생각이 들어서 기본 기능만 작동하도록 플러그인을 만들어 봤다. 개발 환경은 아래와 같다.

  • WordPress : 5.5
  • PHP : 7.4.9
  • ffmpeg : 4.2.4

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;
}

워드프레스 플러그인 적용을 위한 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://chicpro.dev/
Description: This plugin animated gif to mp4 using ffmpeg in post.
Author: chicpro
Version: 1.0.0
Author URI: https://chicpro.dev/
*/

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

add_filter ('the_content', 'convert_gif2mp4', 100);

위 두개의 파일을 wp-content > plugins 폴더 안에 gif2mp4 와같은 폴더를 생성한 후 그 안에 넣어준다. 그런 다음 워드프레스 관리자 페이지에서 플러그인을 활성해 주면 된다. 포스트 내용에 gif 파일이 출력되는 코드에 따라 $pattern = '#<img[^>]*src=[\'"]?(.+\.gif)[\'"]?[^>]*>#i'; 이 부분을 적당히 수정해야 할 수도 있다. 전체 코드는 github 에서 다운로드 할 수 있다.

github repo : https://github.com/chicpro/wordpress-gif2mp4

Post navigation

Previous Post:

NGINX gzip 압축 설정

Next Post:

PHPMailer를 이용한 이메일 발송

12 Commments

  1. 우성짱 says:
    2020-08-21 at 01:51

    완전 좋아요!

    mp4와 webm을 동시에 지원하는 개념이 정말 좋은 것 같습니다.

    선택해서 보여주는 걸까요?

    Reply
    1. 편리 says:
      2020-08-21 at 15:07

      아마 기기에 따라서 선택되어 재생이 될 것으로 생각됩니다.
      외국 쪽 자료에서는 mp4와 webm을 동시에 지원하는 게 많습니다.

      Reply
  2. 우성짱 says:
    2020-08-21 at 17:47

    혹시 그누보드도 가능할까요?

    이미 thisgun님의 https://sir.kr/g5_plugin/7476 플러그인도 있지만

    webm은 지원이 안더라구요.

    그누보드에서 webm까지 한꺼번에 지원되면 정말 좋을 것 같습니다.

    어떤 부분을 바꾸면 될까요?

    Reply
    1. 편리 says:
      2020-08-24 at 11:34

      요즘 그누보드 작업이 별로 없어서요.. ^^;
      근데.. 이미 수정하신 것 같네요. ㅎㅎ

      Reply
  3. 우성짱 says:
    2020-08-21 at 20:21

    참고해서 그누보드 5.4용 플러그인을 수정해보았습니다.

    그런데 출력할 때

    if (is_file($webm))

    이 부분은 그누보드에서 어떻게 처리해야될지 모르겠습니다.

    일단 그냥 if 부분없이 다 출력되도록 했거든요.

    그러니 정상적으로 소스에 webm과 mp4가 둘다 들어갔습니다.

    if webm 부분은 왜 넣었을까요?

    gif 중에 webm 생성이 안되는 파일이 있는건가요?

    Reply
    1. 편리 says:
      2020-08-24 at 11:35

      음.. 저는 거의 습관적으로 파일 유무를 체크하는 것 같습니다.
      테스트 중 webm 파일이 생성되지 않은 경우는 없지만..
      오류라는 건 언제 발생할지 모르니까요..

      Reply
  4. 우성짱 says:
    2020-08-21 at 20:40

    일단 webm과 mp4를 동시에 출력이 되게 설정했습니다.

    플러그인을 수정해서 그누보드 플러그인에 올려도 되겠죠? ^^;;;

    감사합니다.

    Reply
    1. 편리 says:
      2020-08-24 at 11:36

      제 코드가 조금이라도 도움이 됐다면.. 그걸로 만족합니다. 감사합니다.

      Reply
  5. 고맙습니다 says:
    2021-02-21 at 23:43

    안녕하세요 소중한 자료 감사합니다
    다름이 아니라 제가 word press 에서 귀하의 파일 적용해서 잘 테스트 하고,
    갑자기 서버 이전할 일이 생겨 백업 후 서버 옮겼더니 안되네요….
    전 서버에서는 잘 되었는데,,, 혹시 권한 문제인거 같기도 한데
    퍼미션 설정을 제가 놓친게 있을까요
    아니면 제가 뭔가 큰 걸 놓치고 있는걸까요 ㅠㅠ
    고견 기다립니다

    Reply
    1. 편리 says:
      2021-02-22 at 10:18

      안녕하세요.
      먼저 확인해 보셔야할 것이 ffmpeg 패키지가 설치되어 있는지.. php 에서 exec 명령어는 사용이 가능한지 등 입니다. ffmpeg 등이 설치되어 있는데도 파일이 생성되지 않는다면 퍼미션 부분일텐데요.. 쓰기 권한이 있는지 확인해 보셔야할 것으로 생각됩니다.

      Reply
  6. 임팀장 says:
    2024-02-21 at 15:46

    ffmpeg 패키지라는게 정확히 어떤건지 궁금합니다. 워드프레스에 적용했는데 gif가 변환되어 나오지 않아서 뭐가 문제인지 모르겠네요.

    Reply
    1. 편리 says:
      2024-02-22 at 13:30

      안녕하세요.
      ffmpeg는 오픈소스 동영상 처리 패키지라고 하면 될 것 같습니다. 해당 패키지가 서버에 설치되어 있지 않으면 영상으로 변환되지 않습니다.

      Reply

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Recent Posts

  • php 배열 연산에서 + 와 array_merge 의 차이
  • pcntl_fork 를 이용한 다중 프로세스 실행
  • 아이폰 단축어를 이용하여 주중 공휴일엔 알람 울리지 않게 하기
  • 구글 캘린더 전체일정 재동기화
  • OpenLiteSpeed 웹서버에 HTTP 인증 적용
  • OpenLiteSpeed 웹어드민 도메인 연결
  • WireGuard를 이용한 VPN 환경 구축
  • Ubuntu 22.04 서버에 OpenLiteSpeed 웹서버 세팅
  • 맥 vim 세팅
  • 우분투 시스템 터미널쉘 zsh 로 변경

Recent Comments

  • 편리 on 업무관리용 그누보드 게시판 스킨
  • 임종섭 on 업무관리용 그누보드 게시판 스킨
  • 캐논 5D 펌웨어 | Dslr 펌웨어 업그레이드 방법 82 개의 베스트 답변 on 캐논 EOS 30D 펌웨어 Ver 1.0.6 , EOS 5D 펌웨어 Ver 1.1.1
  • Top 5 캐논 5D 펌웨어 Top 89 Best Answers on 캐논 EOS 30D 펌웨어 Ver 1.0.6 , EOS 5D 펌웨어 Ver 1.1.1
  • 편리 on 워드프레스 애니메이션 gif 파일을 mp4로 변환하여 출력하기
  • 임팀장 on 워드프레스 애니메이션 gif 파일을 mp4로 변환하여 출력하기
  • 편리 on Notepad++ NppFTP 플러그인 수동 설치
  • paul-j on Notepad++ NppFTP 플러그인 수동 설치
  • YS on Windows 10 iCloud 사진 저장 폴더 변경
  • 편리 on Docker를 이용한 Centos7 + httpd + php 5.4 개발환경 구축

Meta

  • Log in
  • Entries feed
  • Comments feed
  • WordPress.org
© 2025 CHICPRO | Built using WordPress and SuperbThemes