Top/Windows/Google VideoをAVIに変換

Google VideoをAVIに変換はてなブックマーク

Google VideoからダウンロードできるAVIはDivX4コーデックを使用したAVIですが、余分なチャンクがついているため、Windows Media Playerでは再生出来ません。
そこで、Google VideoのAVIから余分なチャンクを除去するツールを作ってみました。

googlevid2avi.png googlevid2avi 0.0.2 (2006/05/29)

使用方法

  1. Sleipnir用スクリプト Google Video DLを使って、動画をAVIでダウンロードする。
  2. googlevid2avi.png googlevid2avi のアイコンの上に変換したいファイルをドラッグアンドドロップ。
  3. 変換された新規ファイルをWindows Media Playerで再生。
    (再生にはDivX4コーデック*1が必要です。)

ソースコード(Delphi)

googlevid2avi.dpr

  0
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
program googlevid2avi;
 
uses
  Windows, SysUtils, Classes;
 
{$R *.res}
 
type
  TChunk = Packed Record
    ID      : array [1..4] of Char;
    Size    : DWORD;
  end;
  TRIFFChunk = Packed Record
    ID      : array [1..4] of Char;
    Size    : DWORD;
    FormType: array [1..4] of Char;
  end;
  TLISTChunk = Packed Record
    ID      : array [1..4] of Char;
    Size    : DWORD;
    ListType: array [1..4] of Char;
  end;
const
  APP_NAME = 'googlevid2avi';
  NEW_FILE_SUFFIX = '_new.avi';
var
  InputMS : TMemoryStream;
  OutputFS: TFileStream;
  NewFileName: String;
  RiffChunk: TRIFFChunk;
  ListChunk: TLISTChunk;
  GdatChunk: TChunk;
  RiffSize: Integer;
  MovSize: Integer;
  MovData: PByte;
begin
  if ParamCount = 0 then
  begin
    MessageBox(0, '変換したいファイルをドラッグアンドドロップして下さい', APP_NAME, MB_SETFOREGROUND or MB_ICONERROR);
    exit;
  end;
  if ParamCount > 1 then
  begin
    MessageBox(0, '複数ファイルの一括変換には対応していません', APP_NAME, MB_SETFOREGROUND or MB_ICONERROR);
    exit;
  end;
  if not FileExists(ParamStr(1)) then
  begin
    MessageBox(0, '変換元ファイルが存在しません', APP_NAME, MB_SETFOREGROUND or MB_ICONERROR);
    exit;
  end;
  if ExtractFileExt(ParamStr(1)) <> '.avi' then
  begin
    MessageBox(0, '変換元ファイルの拡張子がaviではありません', APP_NAME, MB_SETFOREGROUND or MB_ICONERROR);
    exit;
  end;
 
  NewFileName := ChangeFileExt(ParamStr(1), NEW_FILE_SUFFIX);
  if FileExists(NewFileName) then
  begin
    if MessageBox(0, '変換先ファイルが存在します。上書きしますか?', APP_NAME, MB_SETFOREGROUND or MB_ICONQUESTION or MB_YESNO) <> IDYES then
    begin
      exit;
    end;
  end;
 
  try
    InputMS := TMemoryStream.Create;
    try
      InputMS.LoadFromFile(ParamStr(1));
    except
      MessageBox(0, '変換元ファイルを読み込めませんでした', APP_NAME, MB_SETFOREGROUND or MB_ICONERROR);
      exit;
    end;
    if (InputMS.Read(RiffChunk, SizeOf(TRIFFChunk)) <> SizeOf(TRIFFChunk)) or (RiffChunk.ID <> 'RIFF') or (RiffChunk.FormType <> 'AVI ') then
    begin
      MessageBox(0, 'AVIではないようです', APP_NAME, MB_SETFOREGROUND or MB_ICONERROR);
      exit;
    end;
    if (InputMS.Read(ListChunk, SizeOf(TLISTChunk)) <> SizeOf(TLISTChunk)) or (ListChunk.ID <> 'LIST') or (ListChunk.ListType <> 'goog') then
    begin
      MessageBox(0, 'Google VideoのAVIではないようです', APP_NAME, MB_SETFOREGROUND or MB_ICONERROR);
      exit;
    end;
    if (InputMS.Read(GdatChunk, SizeOf(TChunk)) <> SizeOf(TChunk)) or (GdatChunk.ID <> 'GDAT') then
    begin
      MessageBox(0, 'Google VideoのAVIではないようです', APP_NAME, MB_SETFOREGROUND or MB_ICONERROR);
      exit;
    end;
    InputMS.Seek(GdatChunk.Size, soFromCurrent);
 
    try
      OutputFS := TFileStream.Create(NewFileName, fmCreate or fmOpenWrite or fmShareExclusive);
      OutputFS.Write('RIFF', 4);
      RiffSize := RiffChunk.Size - 8 - ListChunk.Size;
      OutputFS.Write(RiffSize, 4);
      OutputFS.Write('AVI ', 4);
      MovSize := RiffChunk.Size - 4 - 8 - ListChunk.Size;
      GetMem(MovData, MovSize);
      InputMS.Read(MovData^, MovSize);
      OutputFS.Write(MovData^, MovSize);
    except
      MessageBox(0, '変換先ファイルへ書き込めませんでした', APP_NAME, MB_SETFOREGROUND or MB_ICONERROR);
      exit;
    end;
    MessageBox(0, PChar('変換完了'+#10+#13+#10+#13+NewFileName+#10+#13+'として保存しました'), APP_NAME, MB_SETFOREGROUND or MB_ICONINFORMATION);
 
  finally
    InputMS.Free;
    OutputFS.Free;
    FreeMem(MovData);
  end;
end.

基本的なことが良く分かってなさ過ぎてダメだー (^^;

参考

コメント等ありましたらどうぞ :) Permalinkはてなブックマーク

name:
*1 ffdshowのCVS版など
差分 一覧