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

Вниз

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

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

Наверх




Память: 0.48 MB
Время: 0.064 c
15-1338356867
AV
2012-05-30 09:47
2013.03.22
Наглядно изобразить ход работы графиком


2-1328101281
sergeii01
2012-02-01 17:01
2013.03.22
Запись в файл из нескольких потоков


2-1331284249
rraktir
2012-03-09 13:10
2013.03.22
Как сделать маску ввода под проценты?


2-1333239798
toropoff
2012-04-01 04:23
2013.03.22
чтение WMI


15-1347048410
guest
2012-09-08 00:06
2013.03.22
перехват skype..





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский