C# 来自url的xamarin.ios mp3流在结束前停止
我正在用xamarin开发一个ios应用程序,其中包含一些mp3文件,可以在应用程序中播放 我用了这个样品,看起来效果很好 但mp3会在结束前停止,总是在2英尺30英寸左右 这是我使用的代码:C# 来自url的xamarin.ios mp3流在结束前停止,c#,ios,xamarin,xamarin.ios,streaming,C#,Ios,Xamarin,Xamarin.ios,Streaming,我正在用xamarin开发一个ios应用程序,其中包含一些mp3文件,可以在应用程序中播放 我用了这个样品,看起来效果很好 但mp3会在结束前停止,总是在2英尺30英寸左右 这是我使用的代码: public partial class PlayerViewController : UIViewController { NSTimer updatingTimer; StreamingPlayback player; public event EventHandler<
public partial class PlayerViewController : UIViewController
{
NSTimer updatingTimer;
StreamingPlayback player;
public event EventHandler<ErrorArg> ErrorOccurred;
public string SourceUrl { get; private set; }
public string Title { get; private set; }
public PlayerOption PlayerOption { get; private set; }
public bool IsPlaying { get; private set; }
public PlayerViewController (PlayerOption playerOption, string sourceUrl, string title) : base ("PlayerViewController", null)
{
PlayerOption = playerOption;
SourceUrl = sourceUrl;
Title = title;
}
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
this.View = View;
volumeSlider.TouchUpInside += SetVolume;
playPauseButton.TouchUpInside += PlayPauseButtonClickHandler;
headerMusic.Text = this.Title;
}
void SetVolume (object sender, EventArgs e)
{
if (player == null)
return;
player.Volume = volumeSlider.Value;
}
public override void ViewWillAppear (bool animated)
{
base.ViewWillAppear (animated);
Title = PlayerOption == PlayerOption.Stream ? "Stream " : "Stream & Save";
playPauseButton.TitleLabel.Text = "Pause";
timeLabel.Text = string.Empty;
// Create a shared intance session & check
var session = AVAudioSession.SharedInstance ();
if (session == null) {
var alert = new UIAlertView ("Playback error", "Unable to playback stream", null, "Cancel");
alert.Show ();
alert.Clicked += (object sender, UIButtonEventArgs e) => alert.DismissWithClickedButtonIndex (0, true);
} else {
StartPlayback ();
IsPlaying = true;
// Set up the session for playback category
NSError error;
session.SetCategory (AVAudioSessionCategory.Playback, AVAudioSessionCategoryOptions.DefaultToSpeaker);
session.OverrideOutputAudioPort (AVAudioSessionPortOverride.Speaker, out error);
}
}
public override void ViewDidDisappear (bool animated)
{
base.ViewDidDisappear (animated);
if (updatingTimer != null)
updatingTimer.Invalidate ();
if (player != null) {
player.FlushAndClose ();
player = null;
}
}
void PlayPauseButtonClickHandler (object sender, EventArgs e)
{
if (player == null)
return;
if (IsPlaying)
player.Pause ();
else
player.Play ();
var title = IsPlaying ? "Play" : "Pause";
playPauseButton.SetTitle (title, UIControlState.Normal);
playPauseButton.SetTitle (title, UIControlState.Selected);
IsPlaying = !IsPlaying;
}
void StartPlayback ()
{
try {
var request = (HttpWebRequest)WebRequest.Create (SourceUrl);
request.BeginGetResponse (StreamDownloadedHandler, request);
} catch (Exception e) {
string.Format ("Error: {0}", e.ToString ());
}
}
void RaiseErrorOccurredEvent (string message)
{
var handler = ErrorOccurred;
if (handler != null)
handler (this, new ErrorArg { Description = message });
}
void StreamDownloadedHandler (IAsyncResult result)
{
var buffer = new byte [8192];
int l = 0;
int inputStreamLength;
double sampleRate = 0;
Stream inputStream;
AudioQueueTimeline timeline = null;
var request = result.AsyncState as HttpWebRequest;
try {
var response = request.EndGetResponse (result);
var responseStream = response.GetResponseStream ();
if (PlayerOption == PlayerOption.StreamAndSave)
inputStream = GetQueueStream (responseStream);
else
inputStream = responseStream;
using (player = new StreamingPlayback ()) {
player.OutputReady += delegate {
timeline = player.OutputQueue.CreateTimeline ();
sampleRate = player.OutputQueue.SampleRate;
};
InvokeOnMainThread (delegate {
if (updatingTimer != null)
updatingTimer.Invalidate ();
updatingTimer = NSTimer.CreateRepeatingScheduledTimer (0.5, (timer) => RepeatingAction (timeline, sampleRate));
});
while ((inputStreamLength = inputStream.Read (buffer, 0, buffer.Length)) != 0 && player != null) {
l += inputStreamLength;
player.ParseBytes (buffer, inputStreamLength, false, l == (int)response.ContentLength);
InvokeOnMainThread (delegate {
progressBar.Progress = l / (float)response.ContentLength;
});
}
}
} catch (Exception e) {
RaiseErrorOccurredEvent ("Error fetching response stream\n" + e);
Debug.WriteLine (e);
InvokeOnMainThread (delegate {
if (NavigationController != null)
NavigationController.PopToRootViewController (true);
});
}
}
void RepeatingAction (AudioQueueTimeline timeline, double sampleRate)
{
var queue = player.OutputQueue;
if (queue == null || timeline == null)
return;
bool disc = false;
var time = new AudioTimeStamp ();
queue.GetCurrentTime (timeline, ref time, ref disc);
playbackTime.Text = FormatTime (time.SampleTime / sampleRate);
}
string FormatTime (double time)
{
double minutes = time / 60;
double seconds = time % 60;
return String.Format ("{0}:{1:D2}", (int)minutes, (int)seconds);
}
Stream GetQueueStream (Stream responseStream)
{
var queueStream = new QueueStream (Environment.GetFolderPath (Environment.SpecialFolder.Personal) + "/copy.mp3");
var t = new Thread ((x) => {
var tbuf = new byte [8192];
int count;
while ((count = responseStream.Read (tbuf, 0, tbuf.Length)) != 0)
queueStream.Push (tbuf, 0, count);
});
t.Start ();
return queueStream;
}
}
public部分类playervewcontroller:UIViewController
{
NSTimer更新timer;
流媒体播放播放器;
发生公共事件事件处理程序错误;
公共字符串SourceUrl{get;private set;}
公共字符串标题{get;private set;}
公共播放选项播放选项{get;private set;}
公共布尔显示{get;private set;}
公共PlayerOption控制器(PlayerOption,字符串源URL,字符串标题):基本(“PlayerViewController”,null)
{
PlayerOption=PlayerOption;
SourceUrl=SourceUrl;
头衔=头衔;
}
公共覆盖无效ViewDidLoad()
{
base.ViewDidLoad();
这个视图=视图;
volumeSlider.TouchUpInside+=设置音量;
playPauseButton.TouchUpInside+=PlayPauseButtonClickHandler;
headerMusic.Text=此.Title;
}
void SetVolume(对象发送方,事件参数e)
{
if(player==null)
返回;
player.Volume=volumeSlider.Value;
}
公共覆盖无效视图将出现(布尔动画)
{
base.view将显示(动画);
Title=PlayerOption==PlayerOption.Stream?“Stream”:“Stream&Save”;
playPauseButton.TitleLabel.Text=“暂停”;
timeLabel.Text=string.Empty;
//创建共享intance会话并检查
var session=AVAudioSession.SharedInstance();
if(会话==null){
var alert=new UIAlertView(“播放错误”,“无法播放流”,null,“取消”);
alert.Show();
alert.Clicked+=(对象发送者,UIButtonEventArgs e)=>alert.DismissWithClickedButtonIndex(0,true);
}否则{
StartPlayback();
isplay=true;
//设置播放类别的会话
n误差;
session.SetCategory(AVAudioSessionCategory.Playback,AVAudioSessionCategoryOptions.DefaultToSpeaker);
session.OverrideOutputAudioPort(AVAudioSessionPortOverride.Speaker,输出错误);
}
}
公共覆盖无效视图消失(布尔动画)
{
base.viewdide(动画);
if(updateTimer!=null)
updateTimer.Invalidate();
如果(玩家!=null){
player.FlushAndClose();
player=null;
}
}
void PlayPauseButtonClickHandler(对象发送方,事件参数e)
{
if(player==null)
返回;
如果(显示)
player.Pause();
其他的
player.Play();
var title=显示?“播放”:“暂停”;
playPauseButton.SetTitle(标题,uicontrol状态.正常);
playPauseButton.SetTitle(标题,uicontrol状态。选中);
IsPlaying=!IsPlaying;
}
void StartPlayback()
{
试一试{
var request=(HttpWebRequest)WebRequest.Create(SourceUrl);
request.BeginGetResponse(StreamDownloadedHandler,request);
}捕获(例外e){
Format(“错误:{0}”,e.ToString());
}
}
void raiseErrorOccurrentEvent(字符串消息)
{
var handler=erroroccurrent;
if(处理程序!=null)
处理程序(这是新的ErrorArg{Description=message});
}
void StreamDownloadedHandler(IAsyncResult结果)
{
var buffer=新字节[8192];
int l=0;
int输入流长度;
双采样器=0;
流输入流;
AudioQueueTimeline=null;
var request=result.AsyncState作为HttpWebRequest;
试一试{
var response=request.EndGetResponse(结果);
var responseStream=response.GetResponseStream();
如果(PlayerOption==PlayerOption.StreamAndSave)
inputStream=GetQueueStream(responseStream);
其他的
inputStream=responseStream;
使用(player=newstreamingplayback()){
player.OutputReady+=代理{
timeline=player.OutputQueue.CreateTimeline();
sampleRate=player.OutputQueue.sampleRate;
};
调用主线程(委托{
if(updateTimer!=null)
updateTimer.Invalidate();
UpdatengTimer=NSTimer.CreateRepeatingScheduledTimer(0.5,(计时器)=>RepeatingAction(时间线,sampleRate));
});
while((inputStreamLength=inputStream.Read(buffer,0,buffer.Length))!=0&&player!=null){
l+=输入流长度;
player.ParseBytes(buffer,inputStreamLength,false,l==(int)response.ContentLength);
调用主线程(委托{
progressBar.Progress=l/(float)response.ContentLength;
});
}
}
}捕获(例外e){
RaiseErrorOccurrentEvent(“获取响应流时出错\n”+e);
Debug.WriteLine(e);
调用主线程(委托{
if(NavigationController!=null)
NavigationController.PopToRootViewController(真);
});
}
}
无效重复操作(音频队列时间线,双采样器)
{
var queue=player.OutputQueue;
如果(队列==null | |时间线==null)
返回;
布尔盘=假;
var time=新的AudioTimeStamp();
queue.GetCurrentTime(时间线、参考时间、参考光盘);
playbackTime.Text=FormatTime(time.SampleTime/sampleRate);
}
字符串格式化时间(双精度)
int bufferSize = 128 * 1024
int bufferSize = 128 * 128