【问题标题】:Xamarin Shared Project - MP3 StreamingXamarin 共享项目 - MP3 流媒体
【发布时间】:2015-02-20 16:39:54
【问题描述】:

我正在 Xamarin 共享项目中编写一个简单的流式 mp3 播放器。我有 this 解决方案,它与 iOS 完美配合。我也可以使用media player solution for Android(我猜)来实现同样的效果。关于以正确的方式执行此操作以便共享最大代码的任何建议?据我了解,我有以下选择

  1. 编写一个具有基本音频功能的抽象类,如共享流、缓冲等,然后在特定平台中实现它们
  2. 在每个平台特定的解决方案中创建用户控件
  3. 编写可移植类库

我已经通过this,但不确定根据我的要求和手头的情况,哪种方法最明智。

【问题讨论】:

  • 我们有类似的东西,一个适用于 wp8、Android 和 iOS 的 mp3 流媒体解决方案。我们最终创建了一个在所有这些平台上实现的接口。我们使用 MvvmCross 将这些特定于平台的实例连接到我们的核心项目。把界面分享给大家有用吗?
  • 是的,这将非常有帮助。我以前没有使用过 MvvmCross。根据您的经验,有什么问题吗?
  • 我认为 MvvmCross 效果很好。例如 Fragments 存在一些问题,但没有什么是无法解决的。

标签: xamarin


【解决方案1】:

我用这个作为媒体播放器的接口:

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
}

【讨论】:

    猜你喜欢
    • 2011-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多