Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Media";
Текущий архив: 2006.06.18;
Скачать: [xml.tar.bz2];

Вниз

из MPEG4 файла нужно выдернуть несколько ключевых кадров   Найти похожие ветки 

 
GekaNaz ©   (2006-01-13 16:51) [0]

Помогите пожалуйста, как это можно сделать, или где искать про это информацию, думаю это не очень сложно.


 
NailMan ©   (2006-01-13 17:58) [1]

Можно сделать так
1) имея в наличии DirectX SDK, а точнее *.chm со всей писаниной, посмотреть на структуру RIFF-AVI. В конце пожатых AVIшек есть секция с тегом-идентификатором "idx1"

Вот полностью процедура выводящая на форму инфу о размерах потоков авишки:

Procedure TAdvForm.FillInfo(Name:String;Frames:double);
var f:integer;p:pointer;
   PD:PDWORD;
   ID,TIP:DWORD;
   FF,SIZE:DWORD;
   FCC:Array[0..3] of char;
   ds,fs:Double;
   KeyFrames:integer;
   DeltaFrames:integer;
   AudioFrames:Integer;
   TableOffset,Tablesize,nuldd:dword;
   MinKeyFrame,MaxKeyFrame,AverageKeyFrame:DWORD;
   MinDeltaFrame,MaxDeltaFrame,AverageDeltaFrame:DWORD;
   MinAudioFrame,MaxAudioFrame,AverageAudioFrame:DWORD;
   VideoDataSize,AudioDataSize:DWORD;

begin
f:=fileopen(name,fmopenread or fmsharedenynone);
 fileread(f,nuldd,4);
 fileread(f,nuldd,4);
 fileread(f,nuldd,4);
 fileread(f,nuldd,4);
 FF:=0;
 while FF<>$69766f6d do
  begin
   If FCC="JUNK" then
    begin
     fileread(f,nuldd,4);
      GetMem(p,nuldd);
       fileread(f,p^,nuldd);
      Freemem(p);
    end;
    If FCC="LIST" then
     begin
     Fileread(f,size,4);
     Fileread(f,FF,4);
     If FF<>$69766F6D then
      begin
      GetMem(p,size);
       fileread(f,p^,size);
      Freemem(p);
      end else break;
      fileseek(f,-4,1);
     end;
   FileRead(f,nuldd,4);
 end;
 TableOffset:=fileseek(f,0,1);
 TableOffset:=TableOffset+SIZE-4;
 fileseek(f,TableOffset,0);
 fileread(f,nuldd,4);
 fileread(f,TableSize,4);
 GetMem(p,tablesize+4);
  FillChar(P^,TableSize+4,$FF);
  Fileread(f,P^,TableSize);
fileclose(f);
 PD:=P;
  KeyFrames:=0;
  DeltaFrames:=0;
  AudioFrames:=0;
   MinKeyFrame:=$FFFFFFFF;
   MaxKeyFrame:=0;
   AverageKeyFrame:=0;
   MinDeltaFrame:=$FFFFFFFF;
   MaxDeltaFrame:=0;
   AverageDeltaFrame:=0;
   MinAudioFrame:=$FFFFFFFF;
   MaxAudioFrame:=0;
   AverageAudioFrame:=0;
   VideoDataSize:=0;
   AudioDataSize:=0;
  repeat
     ID:=PD^;
     Inc(PD);
     TIP:=PD^;
     Inc(PD);
     Inc(PD);
     SIZE:=PD^;
  //00dc
   If (ID=$63643030) then
    begin
     If TIP=$10 then begin   //KeyFrame
      Inc(KeyFrames);
      If Size<MinKeyFrame then MinKeyFrame:=Size;
      If Size>MaxKeyFrame then MaxKeyFrame:=Size;
      AverageKeyFrame:=AverageKeyFrame+Size;
      end
     else begin             //DeltaFrame
       inc(DeltaFrames);
      If Size<MinDeltaFrame then MinDeltaFrame:=Size;
      If Size>MaxDeltaFrame then MaxDeltaFrame:=Size;
      AverageDeltaFrame:=AverageDeltaFrame+Size;
          end;
     VideoDataSize:=VideoDataSize+Size;
    end;

  //01wb
   If (hiword(ID)=$6277) then
    begin
      inc(AudioFrames);
      If Size<MinAudioFrame then MinAudioFrame:=Size;
      If Size>MaxAudioFrame then MaxAudioFrame:=Size;
      AverageAudioFrame:=AverageAudioFrame+Size;
     AudioDataSize:=AudioDataSize+Size;
    end;
    inc(PD);
  until PD^=$FFFFFFFF;
 Freemem(P);

 AdvForm.SetLanguage(language);

 ds:=VideoDataSize;

 if language=lang_russian then
  begin
   VDataSizeL.Caption:=floattostrf(ds,ffnumber,15,0)+"  Байт  ( "+
                      floattostrf(ds / 1024 / 1024,fffixed,15,3)+"  МБ )";
   ds:=AudioDataSize;
   ADataSizeL.Caption:=floattostrf(ds,ffnumber,15,0)+"  Байт  ( "+
                      floattostrf(ds / 1024 / 1024,fffixed,15,3)+"  МБ )";
  end
 else
  begin
   VDataSizeL.Caption:=floattostrf(ds,ffnumber,15,0)+"  bytes  ( "+
                      floattostrf(ds / 1024 / 1024,fffixed,15,3)+"  Mb )";
   ds:=AudioDataSize;
   ADataSizeL.Caption:=floattostrf(ds,ffnumber,15,0)+"  bytes  ( "+
                      floattostrf(ds / 1024 / 1024,fffixed,15,3)+"  Mb )";
  end;
 ds:=KeyFrames;
 KeyFrL.Caption:=floattostrf(ds,ffnumber,15,0);
 ds:=DeltaFrames;
 DeltaFrL.Caption:=floattostrf(ds,ffnumber,15,0);
 ds:=AudioFrames;
 ASamplesL.Caption:=floattostrf(ds,ffnumber,15,0);

 if KeyFrames=0 then KeyFrames:=1;
 ds:=MinKeyFrame;
 fs:=MaxKeyFrame;
 if language=lang_russian then
  MinMaxKeyFrL.Caption:=floattostrf(ds,ffnumber,15,0)+" / "+floattostrf(fs,ffnumber,15,0)+"  Байт"
 else
  MinMaxKeyFrL.Caption:=floattostrf(ds,ffnumber,15,0)+" / "+floattostrf(fs,ffnumber,15,0)+"  bytes";
 AverageKeyFrame:=Round(AverageKeyFrame / KeyFrames);
 ds:=AverageKeyFrame;
if language=lang_russian then
 AvrgKeyL.Caption:=floattostrf(ds,ffnumber,15,0)+"  Байт"
else
 AvrgKeyL.Caption:=floattostrf(ds,ffnumber,15,0)+"  bytes";

 if DeltaFrames=0 then DeltaFrames:=1;
 ds:=MinDeltaFrame;
 fs:=MaxDeltaFrame;
if language=lang_russian then
 MinMaxDeltaFrL.Caption:=floattostrf(ds,ffnumber,15,0)+" / "+floattostrf(fs,ffnumber,15,0)+"  Байт"
else
 MinMaxDeltaFrL.Caption:=floattostrf(ds,ffnumber,15,0)+" / "+floattostrf(fs,ffnumber,15,0)+"  bytes";

 AverageDeltaFrame:=Round(AverageDeltaFrame / DeltaFrames);
 ds:=AverageDeltaFrame;
if language=lang_russian then
 AvrgDeltaFrL.Caption:=floattostrf(ds,ffnumber,15,0)+"  Байт"
else
 AvrgDeltaFrL.Caption:=floattostrf(ds,ffnumber,15,0)+"  bytes";

 ds:=VideoDataSize / frames / 1024;  //Kbytes per sec
 fs:=(ds * 8 * 1024) / 1000;         //Kbits per sec
if language=lang_russian then
 VBitRateL.Caption:=floattostrf(ds,fffixed,15,3)+"  КБайт/сек ( "+
                   floattostrf(fs,fffixed,15,3)+"  КБит/сек )"
else
 VBitRateL.Caption:=floattostrf(ds,fffixed,15,3)+"  Kbyte/sec ( "+
                   floattostrf(fs,fffixed,15,3)+"  Kbit/sec )";

 if AudioFrames=0 then AudioFrames:=1;
 ds:=MinAudioFrame;
 fs:=MaxAudioFrame;
if language=lang_russian then
 MinMaxSampL.Caption:=floattostrf(ds,ffnumber,15,0)+" / "+floattostrf(fs,ffnumber,15,0)+" Байт"
else
 MinMaxSampL.Caption:=floattostrf(ds,ffnumber,15,0)+" / "+floattostrf(fs,ffnumber,15,0)+" bytes";
 AverageAudioFrame:=Round(AverageAudioFrame / AudioFrames);
 ds:=AverageAudioFrame;
if language=lang_russian then
 AvrgSampL.Caption:=floattostrf(ds,ffnumber,15,0)+"  Байт"
else
 AvrgSampL.Caption:=floattostrf(ds,ffnumber,15,0)+"  bytes";

 ds:=AudioDataSize / frames / 1024;  //Kbytes per sec
 fs:=(ds * 8 * 1024) / 1000;         //Kbits per sec
if language=lang_russian then
 ABitRateL.Caption:=floattostrf(ds,fffixed,15,3)+"  КБайт/сек ( "+
                   floattostrf(fs,fffixed,15,3)+"  КБит/сек )"
else
 ABitRateL.Caption:=floattostrf(ds,fffixed,15,3)+"  Kbyte/sec ( "+
                   floattostrf(fs,fffixed,15,3)+"  Kbit/sec )";

 ds:=DeltaFrames/keyframes;
 DivDeltaKeyL.Caption:=floattostrf(ds,fffixed,15,3);
end;


Думаю поймешь что к чему.

2) Если тебе нужны сами картинки ключевых кадров, то загрузив в граф файло, переходишь на заранее сохраненные в массив номера ключевых кадров и выцепляешь их SampleGrabber-ом, который также подключаешь к графу. Пример использования SampleGrabber-а есть в том самом DX SDK прямо в *.chm-ке.

---
P.L.U.R. and WBR, NailMan aka 2:5020/3337.13


 
GekaNaz ©   (2006-01-13 19:20) [2]

мне нужны именно картинки, если не трудно скажите как их вытащить в отдельные файлы (с видео никогда просто не работал)
и что такое SampleGrabber


 
GekaNaz ©   (2006-01-13 19:33) [3]

Кстати, данная прога нужна для выкладывания картинок на сайт
http://freevideo.tomsk.ru


 
NailMan ©   (2006-01-13 19:46) [4]

С кодом вытаскивания помочь пока не смогу, так как исходники старого плеера где сие делать можно было не сохранились, а в новый плеер пока функции не добавлял увы...

SampleGrabber - это программный фильтр, который загружается в цепочку декодирования фидеопотока(граф) перед фильтром вывода на экран. У него есть метод получения указателя на текущий кадр, который средствами API можно на диск сохранить

---
P.L.U.R. and WBR, NailMan aka 2:5020/3337.13


 
GekaNaz ©   (2006-01-17 13:21) [5]

Может кто-нибудь подскажет еще ?
желательно како-нибудь пример, заранее спасибо :)


 
programania ©   (2006-01-17 20:53) [6]

Сделал запись кадров из divX используя DSPack из progdigy.com
подробнее
http://programania.com/v06_ru.htm
попробовать
http://programania.com/ENJOL.ZIP    840kb
если надо могу надергать исходников что к этому относятся


 
GekaNaz ©   (2006-01-18 12:17) [7]

О, спасибо, а можно исходники ?? если на дельфях, то просто изумительно !


 
GekaNaz ©   (2006-01-18 21:17) [8]

ENJOL.ZIP - не могу найти , где там можно сохранить кадры из видеофайла в картинки на диск ??


 
programania ©   (2006-01-19 19:11) [9]

>GekaNaz ©   (18.01.06 21:17) [8]
>ENJOL.ZIP - не могу найти , где там можно сохранить кадры из видеофайла в картинки на диск ??

Надо нажать M, + справа, указать где фильмы
в списке фильмов запустить фильм X
нажимать K где надо
кадры будут в папке с именем фильма
а при остановке фильма на экране
подробнее
http://programania.com/v06_ru.htm

Смотрите примеры к DSPack из progdigy.com
или как у меня:
Запуск проигрывания:

form1.sampleGrabber1.filterGraph:=filterGraph1;
form1.FilterGraph1.RenderFile("film.avi");
form1.FilterGraph1.Play;

//событие компонента SampleGrabber захват в bTV: tBitmap
procedure TForm1.SampleGrabber1Buffer(sender: TObject; SampleTime: Double;
 pBuffer: Pointer; BufferLen: Integer);
begin
if not eCap then
 SampleGrabber1.GetBitmap(bTV, pBuffer, BufferLen);
eCap:=true;
end;

PROCEDURE kadr1;
var tk:cardinal;
begin
//ожидание захвата кадра
eCap:=false; wkadr:=true; stop:=false;
tk:=getTickCount+4000;
while not eCap and not stop and (getTickCount<tk)do application.processMessages;
wkadr:=false;
end;

PROCEDURE kadr;
var rm,kr,x,y,r:integer;
begin
//захват одного кадра по кнопке
iPA:=false;
rm:=0;
//пропорции кадра
if o.c11 then kr:=(me.rx-me.ry)div 2 else
if o.c34 then kr:=(me.rx-me.ry*4 div 3)div 2 else
kr:=me.rx{width}*o.ok div 100;
if kr<0 then kr:=0;

wKadr:=true;
kadr1;

b.width:=bTV.Width-(rm+kr)*2; b.height:=bTV.Height-rm*2;
b.canvas.copyrect(rect(0,0,b.Width,b.Height+1),
bTV.canvas,rect(kr,0,bTV.Width-kr,bTV.Height+1));
sHeight:=0;sWidth:=0;

bi.width:=b.Width; bi.height:=b.height;
r:=0;

bi.canvas.draw(0,0,b);

 with form1.ImageEnIO1,m[nPlay] do begin
//запись из bitmap в jpg используя компонент imageEN
   dirAvi(nPlay);
   createDir(sp);
   sp:=sp+"\"+kadr_wr(pa);
   params.JPEG_QUALITY:=90; SaveToFile(sp);
 end;

end;

PROCEDURE pKadr;
var
CP,stopPos,r: Int64;
MediaSeeking: IMediaSeeking;
begin
//запись кадров через интервал o.int с позиции pa
with form1 do begin
zKadr0:=true;
wKadr:=true;

zKadr:=true;

FilterGraph1.QueryInterface(IMediaSeeking, MediaSeeking);
MediaSeeking.GetStopPosition(stopPos);
form1.FilterGraph1.pause;
kc:=-1;
stop:=false; iPA:=false;
while (pa<da) and (pa>=0) and  not stop do begin
 application.processMessages;
 r:=pa;
 CP:=r*10000;
 MediaSeeking.SetPositions(CP,AM_SEEKING_AbsolutePositioning,stopPos,AM_SEEKING_NoPositioning);
 if pa>0 then kadr;
 inc(pa,o.int*1000);
 application.processMessages;
end;
form1.FilterGraph1.stop;

nPlay:=0;
zKadr:=false; zKadr0:=false; k1:=false;
nmFirst:=0;
npk:=true;
tv:=false;
application.processMessages;
end;
end;



Страницы: 1 вся ветка

Форум: "Media";
Текущий архив: 2006.06.18;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.5 MB
Время: 0.01 c
15-1148392592
vidiv
2006-05-23 17:56
2006.06.18
как перехватит буфер обмена при вставки в richedit


3-1145888783
linx
2006-04-24 18:26
2006.06.18
Изоляция транзакции


15-1148274904
Александр Иванов
2006-05-22 09:15
2006.06.18
Сумма прописью


15-1148535398
Ega23
2006-05-25 09:36
2006.06.18
С Днём рождения! 25 мая


2-1149081285
Nikolaich
2006-05-31 17:14
2006.06.18
узнать сколько в n-минутах, часов, дней





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский