내 응용 프로그램에서 알림 소리로 재생하려는 작은 mp3 파일이 있습니다. 명확히하기 위해 이미 Resources 아래에 "raw"폴더를 만들고 거기에 내 mp3 파일을 추가했습니다. 첫 번째 패스로 다음과 같이 MediaPlayer를 사용했습니다.
MediaPlayer mPlayer;
mPlayer = MediaPlayer.Create(context, Resource.Raw.warning);
mPlayer.Start();
그리고 그것은 효과가 있었지만 오디오 트랙을 재생하는 것이 아니라 알림으로 사용하고 싶을 때 약간 어색해 보였습니다. 나는 또한 플레이어가 플레이, 처분 등을 완료했는지 확인하기 위해 그 접근 방식에 더 많은 오버 헤드가 있다고 생각합니다.
그래서 SoundPool을 찾아 구현했습니다. 예를 들어 SoundPool에 사운드를로드 할 때 SoundID에 대한 int를 반환 한 다음 나중에 재생할 사운드에 대한 참조로 사용하는 것과 같은 초기 질문이있었습니다. 따라서 이러한 속성을 처리하기 위해 별도의 클래스를 만들어야했습니다.
이것은 내가 지금까지 가지고 있고 작동하는 것처럼 보이지만 이것이 가장 좋은 방법인지 궁금합니다.
먼저 SoundPool을 래핑하는 클래스를 만들었고 SoundID에 대한 클래스도 있습니다.
using Android.Content;
using Android.Media;
namespace PocketPacTracAndroid.Media
{
public class Sounds
{
SoundPool soundPool;
Context context;
int maxStreams = 1;
bool isLoaded = false;
public bool IsLoaded
{
get { return isLoaded; }
}
public Sounds(Context oContext)
{
soundPool = new SoundPool(maxStreams, Stream.Music, 0);
context = oContext;
loadSoundPool();
}
public Sounds(Context oContext, int streams)
{
maxStreams = streams;
soundPool = new SoundPool(maxStreams, Stream.Music, 0);
loadSoundPool();
}
private void loadSoundPool()
{
soundPool.LoadComplete += SoundPool_LoadComplete;
SoundIDs sid = new SoundIDs();
sid.Scan = soundPool.Load(context, Resource.Raw.scan, 1);
sid.PackageAdded = soundPool.Load(context, Resource.Raw.packageAdded, 1);
sid.HubTransfer = soundPool.Load(context, Resource.Raw.hubtransfer, 1);
sid.Alert = soundPool.Load(context, Resource.Raw.alert, 1);
sid.Warning = soundPool.Load(context, Resource.Raw.warning, 1);
sid.ScanChange = soundPool.Load(context, Resource.Raw.scanchange, 1);
}
private void SoundPool_LoadComplete(object sender, SoundPool.LoadCompleteEventArgs e)
{
isLoaded = true;
}
public void playSound(int sid)
{
if (isLoaded)
{
soundPool.Play(sid, 1f, 1f, 1, 0, 1f);
}
}
}
public class SoundIDs
{
int scan;
int packageAdded;
int hubTransfer;
int alert;
int warning;
int scanChange;
public int Scan
{
get { return scan; }
set { scan = value; }
}
public int PackageAdded
{
get { return packageAdded; }
set { packageAdded = value; }
}
public int HubTransfer
{
get { return hubTransfer; }
set { hubTransfer = value; }
}
public int Alert
{
get { return alert; }
set { alert = value; }
}
public int Warning
{
get { return warning; }
set { warning = value; }
}
public int ScanChange
{
get { return scanChange; }
set { scanChange = value; }
}
}
}
그런 다음 앱의 어느 곳에서나 클래스를 인스턴스화합니다.
Sounds sounds;
SoundIDs sid;
public override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
context = Context;
getServiceTypes();
sounds = new Sounds(context);
sid = new SoundIDs();
}
마지막으로 이것을 호출하여 파일을로드 할 때 반환 된 내 soundID를 기반으로 사운드를 재생할 수 있습니다. 또한 외부에서 확인하고 싶은 경우를 대비하여 IsLoaded를 노출했지만 playSound가 호출되면 내부적으로 확인됩니다.
sounds.playSound(sid.Scan);
이것이 좋은 접근 방식처럼 보입니까? 최고인가요? 모든 제안을 주시면 감사하겠습니다. 작동하는 것 같지만 애플리케이션 수명주기 동안 동일하거나 다른 알림을 반복해서 호출하는 경우 리소스 문제 나 재생 문제가 없는지 확인하고 싶습니다.
감사!
예, SoundPool은 갈 길입니다. 스레드가 동시에 다른 소리를 재생하는지주의하십시오. 대기열에 구축하지 않는 한 일부 사운드는 스피커가 하나뿐이므로 다른 사운드를 차단합니다.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다