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

Вниз

Длинна avi файла (некоректно определяет)   Найти похожие ветки 

 
inviz   (2008-12-29 11:51) [0]

Здравствуйте! Возник такой вопрос: как корректно определить длинну воспроизведения avi файла? нарыл в сети функцию

procedure TForm1.ReadAviInfo(FileName: string);
var
 iFileHandle: Integer; // хэндл файла
 // Для позмционирования в AVI файле
 Aviheadersize: integer;
 Vheadersize: integer;
 Aviheaderstart: integer;
 Vheaderstart: integer;
 Aheaderstart: integer;
 Astrhsize: integer;
 // Временные переменные
 TempTest: String[5];
 TempSize: Integer;
 TempVcodec: String[5];
 TempAcodec: integer;
 TempMicrosec: integer;
 TempLengthInFrames: integer;
 TempAchannels: integer;
 TempAsamplerate: integer;
 TempAbitrate: integer;
 //Выходные данные
 Size: double;
 Length: string;
 Vcodec: string;
 Vbitrate: double;
 VWidth: integer;
 VHeight: integer;
 Fps: double;
 LengthInSec: double;
 Acodec: string;
 Abitrate: string;
begin
 // Открываем
 iFileHandle := FileOpen(FileName, fmOpenRead);
 // Грубая проверка на подлинность файла
 FileSeek(iFileHandle, 7, 0);
 FileRead(iFileHandle, TempTest, 5);
 if copy(TempTest, 0, 4) <> "AVI " then
 begin
  MessageDlg("Could not open " + FileName + " because it is not a valid video file", mtError, [mbOk], 0);
  Exit;
 end;
 // Размер файла
 FileSeek(iFileHandle,4,0);
 FileRead(iFileHandle, TempSize, 4);
 // Размер хедера (needed to locate the audio part)
 FileSeek(iFileHandle,28,0);
 FileRead(iFileHandle, Aviheadersize, 4);
 // старт хедера (needed to locate the video part)
 Aviheaderstart := 32;
 // Милисекунды (1000000 / TempMicrosec = fps)
 FileSeek(iFileHandle,Aviheaderstart,0);
 FileRead(iFileHandle, TempMicrosec, 4);
 // Размер во фреймах
 FileSeek(iFileHandle,Aviheaderstart + 16,0);
 FileRead(iFileHandle, TempLengthInFrames, 4);
 // Ширина
 FileSeek(iFileHandle,Aviheaderstart + 32,0);
 FileRead(iFileHandle, VWidth, 4);
 // Высота
 FileSeek(iFileHandle,Aviheaderstart + 36,0);
 FileRead(iFileHandle, VHeight, 4);
 FileSeek(iFileHandle,Aviheaderstart + Aviheadersize + 4,0);
 FileRead(iFileHandle, Vheadersize, 4);
 Vheaderstart := Aviheaderstart + Aviheadersize + 20;
 // кодек
 FileSeek(iFileHandle,Vheaderstart + 3,0);
 FileRead(iFileHandle, TempVCodec, 5);
 Aheaderstart := Vheaderstart + Vheadersize + 8;
 FileSeek(iFileHandle,Aheaderstart - 4,0);
 FileRead(iFileHandle, Astrhsize, 5);
 // Audio codec
 FileSeek(iFileHandle,Aheaderstart + Astrhsize + 8,0);
 FileRead(iFileHandle, TempACodec, 2);
 // Audio каналы (1 = mono, 2 = stereo)
 FileSeek(iFileHandle,Aheaderstart + Astrhsize + 10,0);
 FileRead(iFileHandle, TempAchannels, 2);
 // Audio samplerate
 FileSeek(iFileHandle,Aheaderstart + Astrhsize + 12,0);
 FileRead(iFileHandle, TempAsamplerate, 4);
 // Audio bitrate
 FileSeek(iFileHandle,Aheaderstart + Astrhsize + 16,0);
 FileRead(iFileHandle, TempAbitrate, 4);
 // закрываем файл
 FileClose(iFileHandle);
 // анализируем видео кодек (можно добавить больше)
 Vcodec := copy(TempVcodec, 0, 4);
 if Vcodec = "div2" then Vcodec := "MS MPEG4 v2"
 else if Vcodec = "DIV2" then Vcodec := "MS MPEG4 v2"
 else if Vcodec = "div3" then Vcodec := "DivX;-) MPEG4 v3"
 else if Vcodec = "DIV3" then Vcodec := "DivX;-) MPEG4 v3"
 else if Vcodec = "div4" then Vcodec := "DivX;-) MPEG4 v4"
 else if Vcodec = "DIV4" then Vcodec := "DivX;-) MPEG4 v4"
 else if Vcodec = "div5" then Vcodec := "DivX;-) MPEG4 v5"
 else if Vcodec = "DIV5" then Vcodec := "DivX;-) MPEG4 v5"
 else if Vcodec = "divx" then Vcodec := "DivX 4"
 else if Vcodec = "mp43" then Vcodec := "Microcrap MPEG4 v3";
 // тоже с аудио
 case TempAcodec of
  0: Acodec := "PCM";
  1: Acodec := "PCM";
  85: Acodec := "MPEG Layer 3";
  353: Acodec := "DivX;-) Audio";
  8192: Acodec := "AC3-Digital";
 else
  Acodec := "Unknown (" + IntToStr(TempAcodec) + ")";
 end;
 case (Trunc(TempAbitrate / 1024 * 8)) of
  246..260: Abitrate := "128 Kbit/s";
  216..228: Abitrate := "128 Kbit/s";
  187..196: Abitrate := "128 Kbit/s";
  156..164: Abitrate := "128 Kbit/s";
  124..132: Abitrate := "128 Kbit/s";
  108..116: Abitrate := "128 Kbit/s";
  92..100: Abitrate := "128 Kbit/s";
  60..68: Abitrate := "128 Kbit/s";
 else
  Abitrate := FormatFloat("# Kbit/s", TempAbitrate / 1024 * 8);
 end;
 // тут некоторые вычисления
 Size := TempSize / 1024 / 1024;
 Fps := 1000000 / TempMicrosec; // FPS
 LengthInSec := TempLengthInFrames / fps; // Length in seconds
 Length := FormatFloat("# min", Int(LengthInSec / 60)) + FormatFloat(" # sec",
  Round(LengthInSec - (Int(LengthInSec / 60) * 60)));
 Vbitrate := (TempSize / LengthInSec - TempABitrate) / 1024 * 8;
 // Выводим инфу в мемо
 Memo1.Lines.Add("AVI INFORMATION");
 Memo1.lines.Add("Size: " + FormatFloat("#.## MB",Size));
 Memo1.Lines.Add("Length: " + Length);
 Memo1.Lines.Add("");
 Memo1.Lines.Add("VIDEO INFORMATION");
 Memo1.Lines.Add("Codec: " + Vcodec);
 Memo1.Lines.Add("Bitrate: " + FormatFloat("# Kbit/s", Vbitrate));
 Memo1.lines.Add("Width: " + IntToStr(VWidth) + " px");
 Memo1.lines.Add("Height: " + IntToStr(VHeight) + " px");
 Memo1.Lines.Add("FPS: " + FormatFloat("#.##", fps));
 Memo1.Lines.Add("");
 Memo1.Lines.Add("AUDIO INFORMATION");
 Memo1.Lines.Add("Codec: " + Acodec);
 Memo1.Lines.Add("Bitrate: " + Abitrate);
end;

определение длинны происходит в этих строках

Fps := 1000000 / TempMicrosec; // FPS
 LengthInSec := TempLengthInFrames / fps; // Length in seconds
 Length := FormatFloat("# min", Int(LengthInSec / 60)) + matFloat(" # sec", Round(LengthInSec - (Int(LengthInSec / 60) * 60)));

но как бы я ни крутил она иногда неправельно показывает длительность файла например файл длительностью 02:10:36 определяет как 98 минут :(, для сравнения я запускаю файл в light Alloy, как научить эту функцию работать корректнее? В сети искал но чет алгоритмов определения длительности avi файла исходя из FPS не нашел .Может кто поделится инфой, заранее спасиба


 
Sapersky   (2008-12-29 17:11) [1]

FPS неправильно считается (как минимум).
Когда открывал видео через VFW, считал как
 FFramesPerSecond := Round(FStreamInfo.dwRate / FStreamInfo.dwScale),
где
 FStreamInfo : TAVIStreamInfo;
TAVIStreamInfo = record // см. в хелпе как AVISTREAMINFO
  fccType:               FourCC;
  fccHandler:            FourCC;
  dwFlags:               DWord;
  dwCaps:                DWord;
  wPriority:             Word;
  wLanguage:             Word;
  dwScale:               DWord;
  dwRate:                DWord;
  dwStart:               DWord;
  dwLength:              DWord;
  dwInitialFrames:       DWord;
  dwSuggestedBufferSize: DWord;
  dwQuality:             DWord;
  dwSampleSize:          DWord;
  rectFrame:             TRect;
  dwEditCount:           DWord;
  dwFormatChangeCount:   DWord;
  szName:                array[0..63] of Char;
end;

Похоже, что такая же структура лежит и в файле, Aviheaderstart = смещению dwScale. dwRate, соответственно, это следующий DWord. Хотя обычно там 1000000, но не обязательно.
Ну и кол-во кадров правильнее считать так:
FFrameCnt := FStreamInfo.dwLength - FStreamInfo.dwStart;


 
inviz   (2008-12-29 22:06) [2]

благодарю. буду пробовать...


 
inviz   (2009-01-04 21:52) [3]

С новым годом еще раз  :).

> Sapersky

Слушай друг обьясни пожалуста, если можно на примере или (если есть ссылка на пример) дай ссылку, как открыть avi файл этой VFW библиотекой я нашел ее, скачал шарился в ней так ничего и не понял в инэте мануалов не нашел по использованию :( Понял тока то что нада как то открыть avi-шку функцией AVIFileOpenA или AVIFileOpenW - считать информацию о файле функцией AVIStreamInfoA/AVIStreamInfoW или AVIFileInfo и закрыть файл а вот как это все осуществить не пойму просто никогда не сталкивался с таким :(. Если можно небольшой пример в 3-4 строки как открыть/закрыть файл считать что-нибудь... Заранее спасибо


 
KilkennyCat ©   (2009-01-04 23:12) [4]


> в инэте мануалов не нашел по использованию :(

Не найти документацию по Video For Windows можно только в случае отключенного интернета.


 
Sapersky   (2009-01-04 23:28) [5]

http://sapersky.narod.ru/files/AviHandler_VFW.rar
см. TAviPlayer.Open



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

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

Наверх




Память: 0.49 MB
Время: 0.051 c
2-1337757483
serge
2012-05-23 11:18
2013.03.22
нужна помощь с событием onkeydown


15-1328553855
Hgd1
2012-02-06 22:44
2013.03.22
iMacros в D7


4-1259040937
Alex_C
2009-11-24 08:35
2013.03.22
"Принудительная" запись в COM-порт


2-1338798568
leklerk
2012-06-04 12:29
2013.03.22
Программа висит в процессах


15-1330507432
ПЛОВ2
2012-02-29 13:23
2013.03.22
CompareText и кирилица