Android 从资源中播放.wav文件
我正在使用Firemonkey编写一个android应用程序 因此,我无法使用彩信系统的功能sndPlaySound从资源文件中播放,因为这仅限于Windows Firemonkey支持媒体播放器的工作和资源。但是媒体播放器不能直接使用资源文件 如何使用TMediaPlayer播放资源中的声音 播放不在文件中的媒体 TMediaPlayer不以本机方式实现任何非文件系统数据源, 因此,您必须实现自己的自定义编解码器/媒体类才能访问 (并播放)您想要的资源数据。TMediaPlayer本身就是这样 不管它的文件名是否存在于文件系统中。它只是问 TMediaCodecManager类检索合适的TMedia对象以访问和 播放文件名所指的任何来源的数据 创建从FMX.Media.TMedia派生的自定义类并实现其 根据需要抽象方法(DoPlay()、DoStop()、GetDuration()等)。这 类访问并播放实际的媒体数据,因此您可以传递所需的 文件名,并让它根据需要加载/访问您的资源流。看 例如,在默认的TMedia实现中(FMX.Media.Win.TWindowsMedia, FMX.Media.Mac.TQTMedia等) 创建从FMX.Media.TCustomMediaCodec派生的自定义类并实现 它的抽象CreateFromFile()方法返回自定义 TMedia类。然后,您可以在程序启动时使用 FMX.Media.TMediaCodecManager.registerDiacodeClass()。诀窍在于 您必须使用文件扩展名注册该类,因此请选择一些内容 这是唯一的,对于真正的文件来说不能混淆 例如:Android 从资源中播放.wav文件,android,delphi,audio,firemonkey,Android,Delphi,Audio,Firemonkey,我正在使用Firemonkey编写一个android应用程序 因此,我无法使用彩信系统的功能sndPlaySound从资源文件中播放,因为这仅限于Windows Firemonkey支持媒体播放器的工作和资源。但是媒体播放器不能直接使用资源文件 如何使用TMediaPlayer播放资源中的声音 播放不在文件中的媒体 TMediaPlayer不以本机方式实现任何非文件系统数据源, 因此,您必须实现自己的自定义编解码器/媒体类才能访问 (并播放)您想要的资源数据。TMediaPlayer本身就是这
unit PlayMediaFromResource;
uses
..., FMX.Media;
type
TMyResourceMedia = class(TMedia)
...
protected
function GetDuration: TMediaTime; override;
function GetCurrent: TMediaTime; override;
procedure SetCurrent(const Value: TMediaTime); override;
function GetVideoSize: TPointF; override;
function GetMediaState: TMediaState; override;
function GetVolume: Single; override;
procedure SetVolume(const Value: Single); override;
procedure UpdateMediaFromControl; override;
procedure DoPlay; override;
procedure DoStop; override;
public
constructor Create(const AFileName: string); override;
destructor Destroy; override;
end;
TMyResourceMediaCodec = class(TCustomMediaCodec)
public
function CreateFromFile(const AFileName: string): TMedia; override;
end;
function TMyResourceMediaCodec.CreateFromFile(const AFileName: string): TMedia;
begin
Result := TMyResourceMedia.Create(AFileName);
end;
constructor TMyResourceMedia.Create(const AFileName: string);
var
ResName: string;
begin
ResName := ChangeFileExt(AFileName, ''); // strip off '.myres' file extension
// load resource identified by ResName as needed...
end;
....
initialization
TMediaCodecManager.RegisterMediaCodecClass('.myres', 'My Resource Stream',
TMediaType.Audio, TMyResourceMediaCodec);
然后你可以这样做:
MediaPlayer1.FileName := 'MyResourceName.myres';
MediaPlayer1.Play;
end;
--
或者您可以将资源保存到文件中如果你能以某种方式将资源保存到一个文件中并从那里播放,那么一切都会变得容易得多。您只需使用stock TMediaPlayer即可。
播放完毕后不要忘记删除文件,否则会填满磁盘。 播放不在文件中的媒体 TMediaPlayer不以本机方式实现任何非文件系统数据源, 因此,您必须实现自己的自定义编解码器/媒体类才能访问 (并播放)您想要的资源数据。TMediaPlayer本身就是这样 不管它的文件名是否存在于文件系统中。它只是问 TMediaCodecManager类检索合适的TMedia对象以访问和 播放文件名所指的任何来源的数据 创建从FMX.Media.TMedia派生的自定义类并实现其 根据需要抽象方法(DoPlay()、DoStop()、GetDuration()等)。这 类访问并播放实际的媒体数据,因此您可以传递所需的 文件名,并让它根据需要加载/访问您的资源流。看 例如,在默认的TMedia实现中(FMX.Media.Win.TWindowsMedia, FMX.Media.Mac.TQTMedia等) 创建从FMX.Media.TCustomMediaCodec派生的自定义类并实现 它的抽象CreateFromFile()方法返回自定义 TMedia类。然后,您可以在程序启动时使用 FMX.Media.TMediaCodecManager.registerDiacodeClass()。诀窍在于 您必须使用文件扩展名注册该类,因此请选择一些内容 这是唯一的,对于真正的文件来说不能混淆 例如:
unit PlayMediaFromResource;
uses
..., FMX.Media;
type
TMyResourceMedia = class(TMedia)
...
protected
function GetDuration: TMediaTime; override;
function GetCurrent: TMediaTime; override;
procedure SetCurrent(const Value: TMediaTime); override;
function GetVideoSize: TPointF; override;
function GetMediaState: TMediaState; override;
function GetVolume: Single; override;
procedure SetVolume(const Value: Single); override;
procedure UpdateMediaFromControl; override;
procedure DoPlay; override;
procedure DoStop; override;
public
constructor Create(const AFileName: string); override;
destructor Destroy; override;
end;
TMyResourceMediaCodec = class(TCustomMediaCodec)
public
function CreateFromFile(const AFileName: string): TMedia; override;
end;
function TMyResourceMediaCodec.CreateFromFile(const AFileName: string): TMedia;
begin
Result := TMyResourceMedia.Create(AFileName);
end;
constructor TMyResourceMedia.Create(const AFileName: string);
var
ResName: string;
begin
ResName := ChangeFileExt(AFileName, ''); // strip off '.myres' file extension
// load resource identified by ResName as needed...
end;
....
initialization
TMediaCodecManager.RegisterMediaCodecClass('.myres', 'My Resource Stream',
TMediaType.Audio, TMyResourceMediaCodec);
然后你可以这样做:
MediaPlayer1.FileName := 'MyResourceName.myres';
MediaPlayer1.Play;
end;
--
或者您可以将资源保存到文件中如果你能以某种方式将资源保存到一个文件中并从那里播放,那么一切都会变得容易得多。您只需使用stock TMediaPlayer即可。
播放完毕后不要忘记删除文件,否则会填满磁盘。这不起作用。在这个例子中,我得到了与该类相关的大量错误。“我得到了大量错误”并没有给我们提供太多的信息。祝您好运。例如:
[DCC Error]Unit2.pas(18):在基类[DCC Error]Unit2.pas(45)中找不到E2137方法“GetDuration”:E2004标识符重新声明:“AFileName”[DCC Error]Unit2.pas(73):E2066缺少运算符或分号[DCC Error]Unit2.pas(23):E2065未满足的转发或外部声明:“TForm2.GetVolume”
您刚刚将这些方法塞进了一个表单中。仔细阅读我链接的代码。试着花些时间思考它的作用并理解它。不要只是盲目地将代码粘贴到程序的随机部分,希望它能成功。这是行不通的。在这个例子中,我得到了与该类相关的大量错误。“我得到了大量错误”并没有给我们提供太多的信息。祝您好运。例如:[DCC Error]Unit2.pas(18):在基类[DCC Error]Unit2.pas(45)中找不到E2137方法“GetDuration”:E2004标识符重新声明:“AFileName”[DCC Error]Unit2.pas(73):E2066缺少运算符或分号[DCC Error]Unit2.pas(23):E2065未满足的转发或外部声明:“TForm2.GetVolume”
您刚刚将这些方法塞进了一个表单中。仔细阅读我链接的代码。试着花些时间思考它的作用并理解它。不要只是盲目地将代码粘贴到程序的随机部分,希望它能成功。我自己说得再好不过了:-)我自己说得再好不过了:-)