Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.06.18;
Скачать: CL | DM;

Вниз

из 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 вся ветка

Текущий архив: 2006.06.18;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.045 c
2-1148844071
wsih
2006-05-28 23:21
2006.06.18
image:=TImage.Create(Application);


2-1149192556
Mr tray
2006-06-02 00:09
2006.06.18
сообщение, узнающее координаты выделенного текста


2-1148882517
Belorus
2006-05-29 10:01
2006.06.18
DLL


5-1133558900
Adil
2005-12-03 00:28
2006.06.18
Svyaz mejdu komponentami v odom unite


15-1148312666
Bogdan1024
2006-05-22 19:44
2006.06.18
квартиру в кредит