将AVI嵌入Delphi中的资源文件

发布于 2025-02-05 02:01:43 字数 5489 浏览 4 评论 0原文

我有一个tform,带有tpanel,该链接到tmediaplayer的显示属性。通过选择项目 - >资源和图像我能够将视频插入一个资源文件,其中

  • filename = abc.avi
  • type = rcdata
  • dissideifier = resource_1
unit uForm2;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, 
  System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms,
  Vcl.Dialogs, Vcl.ExtCtrls, Vcl.MPlayer, Vcl.ComCtrls, Mmsystem;
    
type
  TForm2 = class(TForm)
    MediaPlayer1: TMediaPlayer;
    Panel1: TPanel;
    procedure FormCreate(Sender: TObject);
  end;

var
  Form2: TForm2;

implementation

uses
  ShellAnimations;

{$R *.dfm}

procedure TForm2.FormCreate(Sender: TObject);
var
  fs: TFileStream;
  rs: TResourceStream;
  s : String;
  m : TMediaPlayer;
begin
  rs := TResourceStream.Create(hInstance, 'Resource_1', RT_RCDATA);
  s  := ExtractFilePath(Application.ExeName) + 'abc.avi';
  fs := TFileStream.Create(s, fmCreate);
  rs.SaveToStream(fs);
  fs.Free;

  MediaPlayer1.Close;
  MediaPlayer1.FileName := s;
  MediaPlayer1.Open;
  MediaPlayer1.Play;
  MediaPlayer1.Display := Panel1;
end;

编译代码时,我会发现一个错误:

系统中没有安装驱动程序

,实际上“ abc.avi”文件为1 MIB。如果我使用1 Gib Avi,我会发现一个错误:

另一个过程正在使用该文件

我该如何可以作为Delphi Resource 正确播放此AVI?在两种情况下,AVI都没有声音。如果我使用topendialog,则播放视频,但我不希望用户选择任何内容。该视频必须嵌入到编译的可执行文件中。

______________ 更新的代码和错误消息 ______________

tmediaplayer属性: MediaPlayer1.deviceType = dtavivideo

报告了4个错误:

  • 行:res:= tresourcestream.create.create.create(cansperfileext(pchar(lparam1),'''''' '),'rt_rcdata');

2 [dcc32错误] uform2.pas(56):e2035实际参数不足

  • res:= tresourcestream.create.create(canseffileext(pchar(lparam1),'''),'rt_rcdata'rt_rcdata''rt_rcdata' );

3 [dcc32 error] uform2.pas(98):e2026常数表达式预期

  • 线:ccres:fourcc = makefourcc(ord('a''),ord('v'),ord('v'),ord( 'i'),ord(''));

4 [dcc32错误] uform2.pas(146):e2089无效Typecast

  • 线:mmioinstallioproc(ccres,tfnmmioproc(myResourceioproc)(myResourceioproc),mmio_installproc或mmio_installproc或mmio_globalproc);
unit uForm2;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, Vcl.MPlayer, Vcl.ComCtrls, Mmsystem;

type
  TForm2 = class(TForm)
    MediaPlayer1: TMediaPlayer;
    Panel1: TPanel;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure FormShow(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form2: TForm2;

implementation

uses ShellAnimations;

{$R *.dfm}

function MAKEFOURCC(ch0, ch1, ch2, ch3: BYTE): FOURCC;
begin
  Result := DWORD(ch0) or (DWORD(ch1) shl 8) or (DWORD(ch2) shl 16) or (DWORD(ch3) shl 24);
end;

function MyResourceIOProc(lpMMIOInfo: PMMIOInfo; uMessage: UINT; lParam1, lParam2: LPARAM): LRESULT; stdcall;
var
  Res: TResourceStream;

  function GetResourceStream: TResourceStream;
  begin
    Move(lpMMIOInfo.adwInfo, Result, SizeOf(TResourceStream));
  end;

  procedure SetResourceStream(Stream: TResourceStream);
  begin
    Move(Stream, lpMMIOInfo.adwInfo, SizeOf(TResourceStream));
  end;

begin
  case uMessage of
    MMIOM_OPEN: begin
      try
        Res := TResourceStream.Create(ChangeFileExt(PChar(lParam1), ''), 'RT_RCDATA');
      except
        SetResourceStream(nil);
        Exit(MMIOERR_CANNOTOPEN);
      end;
      SetResourceStream(Res);
      lpMMIOInfo.lDiskOffset := 0;
      Exit(MMSYSERR_NOERROR);
    end;
    MMIOM_CLOSE: begin
      Res := GetResourceStream;
      SetResourceStream(nil);
      Res.Free;
      Exit(MMSYSERR_NOERROR);
    end;
    MMIOM_READ: begin
      Res := GetResourceStream;
      Move((PByte(Res.Memory) + lpMMIOInfo.lDiskOffset)^, Pointer(lParam1)^, lParam2);
      Inc(lpMMIOInfo.lDiskOffset, lParam2);
      Exit(lParam2);
    end;
    MMIOM_SEEK: begin
      case lParam2 of
        SEEK_SET: begin
          lpMMIOInfo.lDiskOffset := lParam1;
        end;
        SEEK_CUR: begin
          Inc(lpMMIOInfo.lDiskOffset, lParam1);
        end;
        SEEK_END: begin
          Res := GetResourceStream;
          lpMMIOInfo.lDiskOffset := Res.Size - 1 - lParam1;
        end;
      end;
      Exit(lpMMIOInfo.lDiskOffset);
    end;
  else
    Exit(MMSYSERR_NOERROR);
  end;
end;

const
  ccRES: FOURCC = MAKEFOURCC(Ord('a'), Ord('v'), Ord('i'), Ord(' '));


procedure TForm2.FormCreate(Sender: TObject);

begin
 mmioInstallIOProc(ccRES, TFNMMIOProc(MyResourceIOProc), MMIO_INSTALLPROC or MMIO_GLOBALPROC);
end;

procedure TForm2.FormDestroy(Sender: TObject);
begin
   mmioInstallIOProc(ccRES, nil, MMIO_REMOVEPROC);
end;

procedure TForm2.FormShow(Sender: TObject);
begin
  MediaPlayer1.FileName := 'Resource_1.avi+';
  MediaPlayer1.Open;
  MediaPlayer1.Display:=Panel1;
  MediaPlayer1.Play;
end;

end.

I have a TForm with a TPanel which is linked to the display properties of a TMediaPlayer. By selecting Project -> Resources and Images I was able to insert my video as a resource file, where

  • filename = abc.avi
  • type = RCDATA
  • identifier = Resource_1
unit uForm2;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, 
  System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms,
  Vcl.Dialogs, Vcl.ExtCtrls, Vcl.MPlayer, Vcl.ComCtrls, Mmsystem;
    
type
  TForm2 = class(TForm)
    MediaPlayer1: TMediaPlayer;
    Panel1: TPanel;
    procedure FormCreate(Sender: TObject);
  end;

var
  Form2: TForm2;

implementation

uses
  ShellAnimations;

{$R *.dfm}

procedure TForm2.FormCreate(Sender: TObject);
var
  fs: TFileStream;
  rs: TResourceStream;
  s : String;
  m : TMediaPlayer;
begin
  rs := TResourceStream.Create(hInstance, 'Resource_1', RT_RCDATA);
  s  := ExtractFilePath(Application.ExeName) + 'abc.avi';
  fs := TFileStream.Create(s, fmCreate);
  rs.SaveToStream(fs);
  fs.Free;

  MediaPlayer1.Close;
  MediaPlayer1.FileName := s;
  MediaPlayer1.Open;
  MediaPlayer1.Play;
  MediaPlayer1.Display := Panel1;
end;

When the code is compiled, I get an error:

There is no driver installed in the system

Actually, the "abc.avi" file is 1 MiB. If I use a 1 GiB AVI, I get an error:

The file is being used by another process

How can I play this AVI correctly as a Delphi resource? The AVI in both cases has no sound. If I use a TOpenDialog, the video is played, but I don't want the user to select anything. The video must be embedded in the compiled executable.

______________ Updated code and error messages ______________

TMediaPlayer property:
MediaPlayer1.DeviceType = dtAVIVideo

Reported 4 errors:

1 [dcc32 Error] uForm2.pas(56): E2010 Incompatible types: 'NativeUInt' and 'string'

  • Line: Res := TResourceStream.Create(ChangeFileExt(PChar(lParam1), ''), 'RT_RCDATA');

2 [dcc32 Error] uForm2.pas(56): E2035 Not enough actual parameters

  • Line: Res := TResourceStream.Create(ChangeFileExt(PChar(lParam1), ''), 'RT_RCDATA');

3 [dcc32 Error] uForm2.pas(98): E2026 Constant expression expected

  • Line: ccRES: FOURCC = MAKEFOURCC(Ord('a'), Ord('v'), Ord('i'), Ord(' '));

4 [dcc32 Error] uForm2.pas(146): E2089 Invalid typecast

  • Line: mmioInstallIOProc(ccRES, TFNMMIOProc(MyResourceIOProc), MMIO_INSTALLPROC or MMIO_GLOBALPROC);
unit uForm2;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, Vcl.MPlayer, Vcl.ComCtrls, Mmsystem;

type
  TForm2 = class(TForm)
    MediaPlayer1: TMediaPlayer;
    Panel1: TPanel;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure FormShow(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form2: TForm2;

implementation

uses ShellAnimations;

{$R *.dfm}

function MAKEFOURCC(ch0, ch1, ch2, ch3: BYTE): FOURCC;
begin
  Result := DWORD(ch0) or (DWORD(ch1) shl 8) or (DWORD(ch2) shl 16) or (DWORD(ch3) shl 24);
end;

function MyResourceIOProc(lpMMIOInfo: PMMIOInfo; uMessage: UINT; lParam1, lParam2: LPARAM): LRESULT; stdcall;
var
  Res: TResourceStream;

  function GetResourceStream: TResourceStream;
  begin
    Move(lpMMIOInfo.adwInfo, Result, SizeOf(TResourceStream));
  end;

  procedure SetResourceStream(Stream: TResourceStream);
  begin
    Move(Stream, lpMMIOInfo.adwInfo, SizeOf(TResourceStream));
  end;

begin
  case uMessage of
    MMIOM_OPEN: begin
      try
        Res := TResourceStream.Create(ChangeFileExt(PChar(lParam1), ''), 'RT_RCDATA');
      except
        SetResourceStream(nil);
        Exit(MMIOERR_CANNOTOPEN);
      end;
      SetResourceStream(Res);
      lpMMIOInfo.lDiskOffset := 0;
      Exit(MMSYSERR_NOERROR);
    end;
    MMIOM_CLOSE: begin
      Res := GetResourceStream;
      SetResourceStream(nil);
      Res.Free;
      Exit(MMSYSERR_NOERROR);
    end;
    MMIOM_READ: begin
      Res := GetResourceStream;
      Move((PByte(Res.Memory) + lpMMIOInfo.lDiskOffset)^, Pointer(lParam1)^, lParam2);
      Inc(lpMMIOInfo.lDiskOffset, lParam2);
      Exit(lParam2);
    end;
    MMIOM_SEEK: begin
      case lParam2 of
        SEEK_SET: begin
          lpMMIOInfo.lDiskOffset := lParam1;
        end;
        SEEK_CUR: begin
          Inc(lpMMIOInfo.lDiskOffset, lParam1);
        end;
        SEEK_END: begin
          Res := GetResourceStream;
          lpMMIOInfo.lDiskOffset := Res.Size - 1 - lParam1;
        end;
      end;
      Exit(lpMMIOInfo.lDiskOffset);
    end;
  else
    Exit(MMSYSERR_NOERROR);
  end;
end;

const
  ccRES: FOURCC = MAKEFOURCC(Ord('a'), Ord('v'), Ord('i'), Ord(' '));


procedure TForm2.FormCreate(Sender: TObject);

begin
 mmioInstallIOProc(ccRES, TFNMMIOProc(MyResourceIOProc), MMIO_INSTALLPROC or MMIO_GLOBALPROC);
end;

procedure TForm2.FormDestroy(Sender: TObject);
begin
   mmioInstallIOProc(ccRES, nil, MMIO_REMOVEPROC);
end;

procedure TForm2.FormShow(Sender: TObject);
begin
  MediaPlayer1.FileName := 'Resource_1.avi+';
  MediaPlayer1.Open;
  MediaPlayer1.Display:=Panel1;
  MediaPlayer1.Play;
end;

end.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文