[질문] ffmpeg에서 동영상 스트림을 jpg 이미지로 추출하는 방법

midasyoo의 이미지

안녕하세요.^^

x86 머신에서 ffmpeg을 이용하여
동영상 스트림을 jpg 이미지로 추출하고 싶습니다.

jpg 이미지를 추출할 때의 조건은 "추출된 이미지 파일은 1개로 존재"해야 하는 것입니다.
즉, 다음 동영상 스트림은 새로운 jpg 이미지로 갱신되면서 1개의 동일 이미지 파일로 저장되는 겁니다.

관련 기능이 구현된 C 또는 Java 라이브러리가 어떤 것이 있나요?^^;
제가 잘몰라서 고수님들의 고견을 부탁드립니다.

아니면, 관련 라이브러리가 없다면
어떤 방식으로 프로그래밍을 해야 하나요?^^;

무식해서 죄송합니다.^^; 그래도, 모르는 것보다는 배워서 알고 싶습니다.

drinkme의 이미지

ffmpeg에 보면 해당 기능이 있는걸로 기억합니다.

libavcodec을 써서 decoding하신 후에, jpeg으로 다시 인코딩하면됩니다.
예전에 해 본 기억으로는,
libavcodec에 stream을 계속 밀어넣으면, frame으로 decoding되서 나오거든요.
그걸 다시, jpg으로 만들면 됩니다.

midasyoo의 이미지

'image2' 옵션이 있어서 jpg로 프레임을 디코딩할 수 있습니다.

그런데, 추출되는 jpg 이미지가 예를 들어서 '1.jpg', '2.jpg', ... 처럼 파일 이름이 변경되어서 추출되더라고요.
아무리 옵션을 설정해서 하더라도 한개의 파일로 계속 만들어 낼 수가 없는 것 같더라고요.

즉, 추출되는 이미지의 이름을 'out.jpg'로만 생성되게 하고, 스트림들을 같은 이미지 파일 이름으로 계속 갱신하면 I/O 에러가 발생합니다.^^;

제가 잘 몰라서 그러는데, ffmpeg내의 API가 제가 원하는 기능이 없는 것 같습니다.

기능이 없다면 어떻게 구현을 해야 하나요?^^;

drinkme의 이미지

잘 이해가 안가는데요
jpg가 다중프레임을 지원하던가?
gif나 png면 몰라도...

midasyoo의 이미지

제가 구현하고 싶은 것은 아래와 같은 조건이 있습니다.

- 아래 -
1. 동영상 프레임에서 정지 이미지 파일로 추출하는 이미지 포맷은 jpg 형태
2. 추출한 이미지 파일은 오직 한 개만 존재
3. 동영상의 (N-1)번째 프레임, N번째 프레임, (N+1)번째 프레임은 추출된 이미지 파일에 계속 덮어쓰는 방식으로 생성
4. 마지막 동영상 프레임에서 추출한 이미지 파일은 이전의 동영상 프레임에서 추출한 이미지 파일에 덮어쓰기 때문에, 결국 최근에 추출된 이미지 파일 한 개만 존재

상기 조건과 같이 구현을 하고 싶은데, 어떻게 구현해야 할지 감이 안잡히네요.^^;

송효진의 이미지

http://ffmpeg-php.sourceforge.net/doc/api/ffmpeg_movie.php
ffmpeg api php 모듈입니다.

사용법을 보면
$frame = $movie->getFrame(프레임번호);
$img = $frame->toGDImage();
imagejpeg($img, 'out.jpg');
이런식으로 하도록 되어 있습니다.

ffmpeg api 자체는 c 로 되어 있을것이니,
참조하기에는 좋을것으로 보입니다.

emerge money
http://wiki.kldp.org/wiki.php/GentooInstallSimple - 명령어도 몇 개 안돼요~
http://xenosi.de/

midasyoo의 이미지

ffmpeg-php는 무엇을 의미하는 건가요? ffmpeg을 php와 연동하여 사용한다는 의미인가요?^^; 제가 잘 몰라서...
php는 어떤 경우에 사용하는건가요?^^;

저는 c기반의 ffmpeg 패키지를 다운받아서 설치했습니다.
그리고, 네크워크 카메라를 ffmpeg이 설치된 서버와 이더넷으로 연결하였죠.
이때 동영상을 jpg 이미지 파일로 저장하는 옵션을 이용하여 ffmpeg을 구동시키면, 카메라로 입력되는 영상은 jpg 이미지 파일로 저장이 됩니다.
그런데, ffmpeg내의 코드를 보면 jpg 이미지 파일이 생성될 때, jpg 이미지 파일의 번호가 증가하면서, jpg 이미지 파일의 개수가 증가합니다.
이렇게 되면 언젠가는 jpg 이미지 파일로 하드디스크가 오버플로우되겠죠.

그래서, 오버플로우를 방지코자 최근의 jpg 이미지만 존재하도록 하고 싶은 겁니다.

저는 C이외에 다른 언어는 잘 모르는데 어떻게 해야 하나요?^^;

danskesb의 이미지

그랬다가는 원하는 영상을 얻기 힘든 것 같습니다. 맨 마지막 프레임에 원하는 영상이 온다는 보장을 하기 힘들거든요.

목적이 디스크 공간 넘침 방지라면, 무조건 가장 최근 하나만 유지시키기보다는 일정한 갯수 이상의 파일이 기록되면 이전 파일을 삭제하는 쪽으로 가시는 게 어떨까요?

---- 절취선 ----
http://blog.peremen.name

midasyoo의 이미지

원하는 영상을 얻는 것은 아니고 가장 최근의 영상만 얻으면 되고, 또한 'I frame'만 추출하여 이미지 파일에 덮어쓰면 되지 않을까요?^^;
그건 그렇고...

일정 개수의 이미지 파일을 만들어 두어서 가장 먼저 만들어진 이미지 파일에 가장 최근 추출한 이미지 파일을 덮어쓰려면 어떻게 구현해야 하나요?^^;

구현 방법을 잘 몰라서...^^;

midasyoo의 이미지

상기의 peremen님의 답글을 리플하려다가 잘못썼네요.^^; 지우려고해도 지우는 방법도 모르겠고...^^;

송효진의 이미지

ffmpeg 를 api 로 사용하고자 한다면 위의 php 바인딩을 참조하시면 ffmpeg 을 c 프로그램으로 제어하실 수 있습니다.
위의 api 얘기가 나오는걸로 봐서는 이미 그런식으로 하시는것 같기는 한데,
같은 파일 오류라는 것을 제가 이해하지 못한걸지도 모르겠네요.

그냥 바이너리로 사용하고자 한다면 -t 옵션인지 -ss 옵션인지가 있는데,
그걸로 몇초만 재생하고 끝낼 수 있습니다.
그렇게 반복을 하는 것은 어떤가요?

-vframes 옵션도 있네요.

emerge money
http://wiki.kldp.org/wiki.php/GentooInstallSimple - 명령어도 몇 개 안돼요~
http://xenosi.de/

midasyoo의 이미지

'image2' 옵션이 입력 동영상을 jpg 이미지 파일로 변환할 수 있습니다.
그런데, 이 옵션에서 제공하고 있는 기능은 '1.jpg', '2.jpg', '3.jpg', ... 등으로 증가하는 이미지 파일이 생성되는 기능입니다.

따라서, 오직 한 개의 jpg 이미지 파일만 생성되는 것이 아니라 무수히 많은 jpg 이미지 파일이 증가하면서 생성되는 겁니다.

저는 오직
"한 개의 jpg 이미지 파일만 생성하고, 그 jpg 이미지 파일에 최근 동영상 프레임을 jpg 이미지로 추출해서 계속 덮어쓰는 기능"을 생각하고 있습니다.
그러면, 이 한 개의 jpg 파일만 주기적으로 읽어 들이면, 사진을 보듯이 갱신되는 jpg 이미지를 볼 수 있겠죠?

그런데, 이런 식으로 구현을 하려면 어떤 식으로 구현을 해야 할 지 잘 모르겠네요.^^;

lifthrasiir의 이미지

그 기능이 왜 필요한지를 설명해 주시면 답변에 더 도움이 되지 않을까 싶습니다. 단순히 파일 이름이 바뀌는 걸 해결하려면 사실 셸 스크립트를 동시에 돌려도 되고요.

세이군의 이미지

혹시 이런게 아닐까 하는데요.
예전에 이글루가 이전할 때 서버를 죽이지 않고 이전을 했습니다. 그러면서 홈페이지에 노호혼과 시계가 있는 사진이 있었습니다.
기억이 맞다면 그 사진은 파일명은 하나였고 새로고침할때마다 다른 사진이 보였습니다.
그와 비슷한 것이 요구되는 상황이 아닐까 하네요.

관련 포스트 : http://www.hof.pe.kr/wp/archives/2120/

midasyoo의 이미지

'세이군'님께서 저의 의도를 아시는 것 같습니다.^^;

midasyoo의 이미지

1. 상기에 기술된 '세이군'님의 말씀처럼
관련 사이트(http://www.hof.pe.kr/wp/archives/2120/)에서 서술한 내용중에

"사무실 한켠에서 노호혼과 이글루스컵, 그리고 미니 벽시계로 10초마다 사진을 찍어 전송하고 있습니다."

라는 부분이 있는데, 자세한 자료는 관련 웹캠이 동작이 보증되지 않아서 확인을 못했습니다.
그렇지만, 아래의 '세이군'님의 말씀처럼

"기억이 맞다면 그 사진은 파일명은 하나였고 새로고침할때마다 다른 사진이 보였습니다."

라는 기능으로 동작했을수도 있겠죠. 이것이 제가 원하는 기능인것 같습니다.^^;

다시 자세히 말씀드리면,
"이미지 파일명은 오직 한 개이고, 그 이미지 파일명에 새로운 이미지를 덮어써서 갱신하는 기능"을 구현하고 싶습니다.

2. 그리고, 이러한 기능이 필요한 것은 단말기의 성능 때문입니다. 또한, 제나름대로 가장 쉽게 구현하는 방법을 선택한 것이고요.
네트워크 카메라에서 보내는 동영상은 ffmpeg의 옵션에 따라서 '동영상을 jpg 이미지로 추출'할 수 있습니다.
그리고, 그 jpg 이미지를 단말기로 전송해서 단말기의 이미지 뷰어로 보고 싶습니다.
따라서, 네트워크 카메라에서 보내는 동영상을 관리하기 편하게 오직 한 개의 jpg 이미지 파일명으로 만들어 놓습니다. 그 jpg 이미지 파일에는 주기적으로 동영상의 jpg 이미지 파일이 갱신되겠죠.

여기서 주기적으로 갱신되는 jpg 이미지 파일만 단말기 쪽으로 전송하면, 단말기에서는 jpg 이미지 파일을 오픈해서 보기만 하면 됩니다.

결국, 단말기의 성능 및 지원환경을 충족시켜야 하는데서 출발했고, 최소의 부분만 구현하여 가비지를 최소화하려는 겁니다.

그런데, 어떻게 구현을 해야 할지 잘 모르겠습니다.^^;

3. 셸 스크립트를 동시에 돌리면 어떻게 동작이 되는 건가요? 사실 제가 셸 스크립트는 잘 모르고 있어서요.^^;
셸 스크립트 방식으로 한다면 관련된 자세한 설명 부탁드려도 될까요?^^;

세이군의 이미지

한가지 구현 방식은 이렇습니다.
OS에 따라서 가능할수도 불가능할수도 있습니다.

ffmpeg를 통해서 나오는 이미지를 임의의 파일명(예를 들면 타임스탬프.jpg)으로 저장하게 해두고 current.jpg로 심볼릭링크하게 만듭니다.
그리고 단말기는 current.jpg를 보는 거죠

midasyoo의 이미지

파일의 심볼릭 링크를 거는 방법은 좋은 아이디어 같은데,
'세이군'님의 말씀에서 하기의 기술 내용처럼

"ffmpeg를 통해서 나오는 이미지를 임의의 파일명(예를 들면 타임스탬프.jpg)으로 저장"

할 때가 역시 고민 사항이네요.

'타임스탬프.jpg' 형태로 저장시, '1.jpg', '2.jpg'... 처럼 jpg 이미지 파일들이 증가되면서 만들어 지겠죠?
결국, 한 개의 파일만 생성하는 방법에 대한 사항은 아닌것 같네요.^^;

아닌가요? 혹시 제가 잘못 이해하고 있다면 바로 지적해 주세요.^^;

송효진의 이미지

위에 적은 제 의견의 핵심은 두가지 입니다.
1. c api
2. -vframes 1 옵션으로 한번 실행시 하나의 파일만 생성하고 종료. sleep 을 줘서 초단위로 반복.

emerge money
http://wiki.kldp.org/wiki.php/GentooInstallSimple - 명령어도 몇 개 안돼요~
http://xenosi.de/

midasyoo의 이미지

'송효진'님께서 말씀하신 하기의 내용에서
ffmpeg-php 연동을 하고 c api만 호출해서 구현하면, 'out.jpg'라는 한 개의 jpg 이미지만 생기는 것 같습니다.
그리고, 갱신되는 이미지 또한 'out.jpg' 파일에 덮어쓰는 형식이 될 것 같고요.
제가 의도하는 것과 맞는 것 같습니다.

그런데, 제가 php를 전혀 모릅니다.^^;
php라는 것이 gcc 및 링커 같은 c 개발 sdk를 말씀하시는 건가요? gcc 설치하듯이 php를 설치해서 사용하는 건가요?^^;
죄송하지만, 자세한 설명 부탁드려도 될까요?^^;

그리고, 프롬프트같이 생긴 '$'는 무엇을 의미하는 건가요?^^;
"$frame->toGDImage()" 메소드를 보면 GD가 설치안되면 이 함수 사용이 불가능한데, GD는 무엇인가요?^^;

상기 내용에 대한 멘토링 부탁드려도 될까요?^^;

-------------------------------------------------------------------------------------------------------------------------
http://ffmpeg-php.sourceforge.net/doc/api/ffmpeg_movie.php ffmpeg api php 모듈입니다.

사용법을 보면
$frame = $movie->getFrame(프레임번호);
$img = $frame->toGDImage();
imagejpeg($img, 'out.jpg');
이런식으로 하도록 되어 있습니다.

ffmpeg api 자체는 c 로 되어 있을것이니,
참조하기에는 좋을것으로 보입니다.

emerge money
http://wiki.kldp.org/wiki.php/GentooInstallSimple - 명령어도 몇 개 안돼요~
http://xenosi.de/
-------------------------------------------------------------------------------------------------------------------------

송효진의 이미지

php 를 하시라는 것이 아닙니다.
ffmpeg 의 api 는 c 입니다.
그 c api 를 php 가 이용할 수 있도록 한 프로젝트의 링크를 걸어드린 이유는,
그것의 소스를 보면, ffmpeg 를 어떻게 c 로 제어할 수 있는지를 쉽게 보실 수 있을 것 같아서 였습니다.

php 는 웹에 특화된 스크립트 언어 입니다.
php 의 문법을 전혀 모르는 상태에서 php 설치하고 거기에 ffmpeg-php 를 올려서 php 문법을 익혀 작성하는것 보다는,
ffmpeg c api 를 이용하는 방법을 알아내시는게 쉬우실것 같네요.

ffmpeg api 문서 자체도 있다는 생각을 못했었네요.ㅎㅎ
http://ffmpeg.org/documentation.html

요게 예제로 적당할 것 같습니다.
http://www.dranger.com/ffmpeg/tutorial01.html

emerge money
http://wiki.kldp.org/wiki.php/GentooInstallSimple - 명령어도 몇 개 안돼요~
http://xenosi.de/

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.