Xamarin 共享项目 - MP3 流
Xamarin Shared Project - MP3 Streaming
我正在 Xamarin 共享项目中编写一个简单的流式 mp3 播放器。我有 this solution which works perfectly with iOS. I can also use the media player solution 和 Android(我猜)来达到同样的效果。关于以正确的方式执行此操作以共享最大代码的任何建议?据我了解,我有以下选项
- 写一个摘要 class 共享基本的音频功能,如流式传输、缓冲等,然后在特定平台中实现它们
- 在每个平台特定的解决方案中创建用户控件
- 写一个可移植的Class库
我已经完成 this,但不确定根据我的要求和手头的情况,哪种方法是最明智的。
我将其用作媒体播放器的界面:
public delegate void StatusChangedEventHandler(object sender, EventArgs e);
public delegate void CoverReloadedEventHandler(object sender, EventArgs e);
public delegate void PlayingEventHandler(object sender, EventArgs e);
public delegate void BufferingEventHandler(object sender, EventArgs e);
/// <summary>
/// The main purpose of this class is to be a controlling unit for all the single MediaItem implementations, who
/// in themselve can play their media, but need a central controling unit, surrounding them
/// </summary>
public interface IMediaPlayer
{
/// <summary>
/// Reading the current status of the player (STOPPED, PAUSED, PLAYING, LOADING - initialization and buffering is combined here)
/// </summary>
PlayerStatus Status { get; }
/// <summary>
/// Raised when the status changes (playing, pause, buffering)
/// </summary>
event StatusChangedEventHandler StatusChanged;
/// <summary>
/// Raised when the cover on the player changes
/// </summary>
event CoverReloadedEventHandler CoverReloaded;
/// <summary>
/// Raised at least every second when the player is playing.
/// </summary>
event PlayingEventHandler Playing;
/// <summary>
/// Raised each time the buffering is updated by the player.
/// </summary>
event BufferingEventHandler Buffering;
/// <summary>
/// Starts playing from the current position
/// </summary>
Task Play();
/// <summary>
/// Stops playing
/// </summary>
Task Stop();
/// <summary>
/// Stops playing but retains position
/// </summary>
Task Pause();
/// <summary>
/// Gets the players position in milliseconds
/// </summary>
int Position { get; }
/// <summary>
/// Gets the source duration in milliseconds
/// If the response is -1, the duration is unknown or the player is still buffering.
/// </summary>
int Duration { get; }
/// <summary>
/// Gets the buffered time in milliseconds
/// </summary>
int Buffered { get; }
/// <summary>
/// Gets the current cover. The class for the instance depends on the platform.
/// Returns NULL if unknown.
/// </summary>
object Cover { get; }
/// <summary>
/// Changes position to the specified number of milliseconds from zero
/// </summary>
Task Seek(int position);
/// <summary>
/// Should be the same as calling PlayByPosition(Queue.size()+1)
/// Maybe you'll want to preload the next song into memory ...
/// </summary>
Task PlayNext();
/// <summary>
/// Start playing if nothing is playing, otherwise it pauses the current media
/// </summary>
Task PlayPause();
/// <summary>
/// Should be the same as calling PlayByPosition(Queue.size()-1).
/// Maybe you'll want to keep the last song in memory ...
/// </summary>
Task PlayPrevious();
/// <summary>
/// Start playing a track by its position in the Queue
/// </summary>
Task PlayByPosition(int index);
}
我还有一个自定义队列,可能对你有帮助:
public interface IQueue : ICollection<Track>, INotifyCollectionChanged, INotifyPropertyChanged
{
/// <summary>
/// Activates or deactivates the Repeat option
/// </summary>
bool Repeat { get; set; }
/// <summary>
/// Activates or deactivates the Shuffle option
/// </summary>
bool Shuffle { get; set; }
/// <summary>
/// If the Queue has a next track
/// </summary>
bool HasNext();
/// <summary>
/// If the Queue has a previous track
/// </summary>
bool HasPrevious();
/// <summary>
/// Get the current track from the Queue
/// </summary>
Track Current { get; }
/// <summary>
/// Get the current playing index the Queue
/// </summary>
int Index { get; }
void setPreviousAsCurrent();
void setNextAsCurrent();
void setIndexAsCurrent(int index);
void AddRange(IEnumerable<Track> items);
}
我的玩家状态是:
public enum PlayerStatus
{
STOPPED,
PAUSED,
PLAYING,
LOADING
}
我正在 Xamarin 共享项目中编写一个简单的流式 mp3 播放器。我有 this solution which works perfectly with iOS. I can also use the media player solution 和 Android(我猜)来达到同样的效果。关于以正确的方式执行此操作以共享最大代码的任何建议?据我了解,我有以下选项
- 写一个摘要 class 共享基本的音频功能,如流式传输、缓冲等,然后在特定平台中实现它们
- 在每个平台特定的解决方案中创建用户控件
- 写一个可移植的Class库
我已经完成 this,但不确定根据我的要求和手头的情况,哪种方法是最明智的。
我将其用作媒体播放器的界面:
public delegate void StatusChangedEventHandler(object sender, EventArgs e);
public delegate void CoverReloadedEventHandler(object sender, EventArgs e);
public delegate void PlayingEventHandler(object sender, EventArgs e);
public delegate void BufferingEventHandler(object sender, EventArgs e);
/// <summary>
/// The main purpose of this class is to be a controlling unit for all the single MediaItem implementations, who
/// in themselve can play their media, but need a central controling unit, surrounding them
/// </summary>
public interface IMediaPlayer
{
/// <summary>
/// Reading the current status of the player (STOPPED, PAUSED, PLAYING, LOADING - initialization and buffering is combined here)
/// </summary>
PlayerStatus Status { get; }
/// <summary>
/// Raised when the status changes (playing, pause, buffering)
/// </summary>
event StatusChangedEventHandler StatusChanged;
/// <summary>
/// Raised when the cover on the player changes
/// </summary>
event CoverReloadedEventHandler CoverReloaded;
/// <summary>
/// Raised at least every second when the player is playing.
/// </summary>
event PlayingEventHandler Playing;
/// <summary>
/// Raised each time the buffering is updated by the player.
/// </summary>
event BufferingEventHandler Buffering;
/// <summary>
/// Starts playing from the current position
/// </summary>
Task Play();
/// <summary>
/// Stops playing
/// </summary>
Task Stop();
/// <summary>
/// Stops playing but retains position
/// </summary>
Task Pause();
/// <summary>
/// Gets the players position in milliseconds
/// </summary>
int Position { get; }
/// <summary>
/// Gets the source duration in milliseconds
/// If the response is -1, the duration is unknown or the player is still buffering.
/// </summary>
int Duration { get; }
/// <summary>
/// Gets the buffered time in milliseconds
/// </summary>
int Buffered { get; }
/// <summary>
/// Gets the current cover. The class for the instance depends on the platform.
/// Returns NULL if unknown.
/// </summary>
object Cover { get; }
/// <summary>
/// Changes position to the specified number of milliseconds from zero
/// </summary>
Task Seek(int position);
/// <summary>
/// Should be the same as calling PlayByPosition(Queue.size()+1)
/// Maybe you'll want to preload the next song into memory ...
/// </summary>
Task PlayNext();
/// <summary>
/// Start playing if nothing is playing, otherwise it pauses the current media
/// </summary>
Task PlayPause();
/// <summary>
/// Should be the same as calling PlayByPosition(Queue.size()-1).
/// Maybe you'll want to keep the last song in memory ...
/// </summary>
Task PlayPrevious();
/// <summary>
/// Start playing a track by its position in the Queue
/// </summary>
Task PlayByPosition(int index);
}
我还有一个自定义队列,可能对你有帮助:
public interface IQueue : ICollection<Track>, INotifyCollectionChanged, INotifyPropertyChanged
{
/// <summary>
/// Activates or deactivates the Repeat option
/// </summary>
bool Repeat { get; set; }
/// <summary>
/// Activates or deactivates the Shuffle option
/// </summary>
bool Shuffle { get; set; }
/// <summary>
/// If the Queue has a next track
/// </summary>
bool HasNext();
/// <summary>
/// If the Queue has a previous track
/// </summary>
bool HasPrevious();
/// <summary>
/// Get the current track from the Queue
/// </summary>
Track Current { get; }
/// <summary>
/// Get the current playing index the Queue
/// </summary>
int Index { get; }
void setPreviousAsCurrent();
void setNextAsCurrent();
void setIndexAsCurrent(int index);
void AddRange(IEnumerable<Track> items);
}
我的玩家状态是:
public enum PlayerStatus
{
STOPPED,
PAUSED,
PLAYING,
LOADING
}