android - 从资源播放.wav文件

标签 android delphi audio firemonkey

我正在使用Firemonkey 编写android应用

因此,我不能使用MMSystem的函数sndPlaySound从资源文件中播放,因为那仅是Windows。

Firemonkey支持媒体播放器的工作和资源。但是媒体播放器不能直接使用资源文件。

如何使用TMediaPlayer播放资源中的声音?

最佳答案

To quote Remy Lebeau (TeamB):

播放不在文件中的媒体

TMediaPlayer does not natively implement any non-filesystem data sources, so you will have to implement your own custom codec/media classes to access (and play) the resource data however you want. TMediaPlayer itself does not care if its FileName exists on a filesystem or not. It simply asks the TMediaCodecManager class to retreive a suitable TMedia object to access and play the data from whatever source the FileName refers to.

Create a custom class that derives from FMX.Media.TMedia and implement its abstract methods as needed (DoPlay(), DoStop(), GetDuration(), etc). This class accesses and plays the actual media data, so you can pass the desired FileName to it and have it load/access your resource stream as needed. Look at the default TMedia implementations for examples (FMX.Media.Win.TWindowsMedia, FMX.Media.Mac.TQTMedia, etc).

Create a custom class that derives from FMX.Media.TCustomMediaCodec and implement its abstract CreateFromFile() method to return an instance of your custom TMedia class. You can then register this class at program startup using FMX.Media.TMediaCodecManager.RegisterMediaCodecClass(). The trick is that you have to register the class using a file extension, so pick something that is unique and cannot be confused for a real file.



例如:
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;

-

或者您可以将资源保存到文件中
如果您能以某种方式将资源保存到文件并从那里播放,那么一切将变得更加容易。您可以只使用库存的TMediaPlayer。
播放完毕后,别忘了删除文件,否则会填满磁盘。

关于android - 从资源播放.wav文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36201749/

相关文章:

java - EditText 没有为测验应用程序的满分添加分数

java - 如何解决lint warning "field is never used"but it is serialized

matlab - 如何使用Matlab准确地以高BPM输出生成的心跳信号?

android - Android Studio Gradle构建脚本不起作用

java - 将 Java 1.8 用于 Android 项目

Delphi 7 - 使用 Canvas 绘制带有透明核心的圆

delphi - 对于 64 位构建,Trunc() 对于高 Int64 失败

oracle - 如果使用 Oracle 数据库,Delphi 应用程序从 BDE 迁移的选项有哪些

python - 如何使用 ffmpeg 从 .wav 文件中获取等间距的音频 block ?

audio - 跨平台音频分析库