C# 当屏幕关闭时,mp3停止播放

C# 当屏幕关闭时,mp3停止播放,c#,ios,xamarin,xamarin.ios,streaming,C#,Ios,Xamarin,Xamarin.ios,Streaming,我正在开发一个应用程序,我需要从url播放音乐。 我使用的是代码,它工作得很好。 但是,当播放歌曲时,屏幕关闭,音乐停止。我需要音乐继续播放直到结束,即使屏幕关闭 我想我必须更改此文件,但我不知道如何: using System; using AudioToolbox; using System.Threading; using System.Collections.Generic; using System.Linq; namespace SecondoSenso { /// <sum

我正在开发一个应用程序,我需要从url播放音乐。 我使用的是代码,它工作得很好。 但是,当播放歌曲时,屏幕关闭,音乐停止。我需要音乐继续播放直到结束,即使屏幕关闭

我想我必须更改此文件,但我不知道如何:

using System;
using AudioToolbox;
using System.Threading;
using System.Collections.Generic;
using System.Linq;

namespace SecondoSenso
{
/// <summary>
/// A Class to hold the AudioBuffer with all setting together
/// </summary>
internal class AudioBuffer
{

    public IntPtr Buffer { get; set; }

    public List<AudioStreamPacketDescription> PacketDescriptions { get; set; }

    public int CurrentOffset { get; set; }

    public bool IsInUse { get; set; }
}

/// <summary>
/// Wrapper around OutputQueue and AudioFileStream to allow streaming of various filetypes
/// </summary>
public class StreamingPlayback : IDisposable
{
    public bool boolDispose = false;

    public event EventHandler Finished;
    public event Action<OutputAudioQueue> OutputReady;

    // the AudioToolbox decoder
    AudioFileStream fileStream;
    int bufferSize = 128 * 256;
    List<AudioBuffer> outputBuffers;
    AudioBuffer currentBuffer;
    // Maximum buffers
    int maxBufferCount = 4;
    // Keep track of all queued up buffers, so that we know that the playback finished
    int queuedBufferCount = 0;
    // Current Filestream Position - if we don't keep track we don't know when to push the last uncompleted buffer
    long currentByteCount = 0;
    //Used to trigger a dump of the last buffer.
    bool lastPacket;

    public OutputAudioQueue OutputQueue;

    public bool Started  { get; private set; }

    public float Volume {
        get {
            return OutputQueue.Volume;
        }

        set {
            OutputQueue.Volume = value;
        }
    }

    /// <summary>
    /// Defines the size forearch buffer, when using a slow source use more buffers with lower buffersizes
    /// </summary>
    public int BufferSize {
        get {
            return bufferSize;
        }

        set {
            bufferSize = value;
        }
    }

    /// <summary>
    /// Defines the maximum Number of Buffers to use, the count can only change after Reset is called or the
    /// StreamingPlayback is freshly instantiated
    /// </summary>
    public int MaxBufferCount {
        get {
            return maxBufferCount;
        }

        set {
            maxBufferCount = value;
        }
    }

    public StreamingPlayback () : this (AudioFileType.MP3)
    {
    }

    public StreamingPlayback (AudioFileType type)
    {
        fileStream = new AudioFileStream (type);
        fileStream.PacketDecoded += AudioPacketDecoded;
        fileStream.PropertyFound += AudioPropertyFound;
    }

    public void Reset ()
    {
        if (fileStream != null) {
            fileStream.Close ();
            fileStream = new AudioFileStream (AudioFileType.MP3);
            currentByteCount = 0;
            fileStream.PacketDecoded += AudioPacketDecoded;
            fileStream.PropertyFound += AudioPropertyFound;
        }
    }

    public void ResetOutputQueue ()
    {
        if (OutputQueue != null) {
            OutputQueue.Stop (true);
            OutputQueue.Reset ();
            foreach (AudioBuffer buf in outputBuffers) {
                buf.PacketDescriptions.Clear ();
                OutputQueue.FreeBuffer (buf.Buffer);
            }
            outputBuffers = null;
            OutputQueue.Dispose ();
        }
    }

    /// <summary>
    /// Stops the OutputQueue
    /// </summary>
    public void Pause ()
    {
        OutputQueue.Pause ();
        Started = false;
    }

    /// <summary>
    /// Starts the OutputQueue
    /// </summary>
    public void Play ()
    {
        OutputQueue.Start ();
        Started = true;
    }

    /// <summary>
    /// Main methode to kick off the streaming, just send the bytes to this method
    /// </summary>
    public void ParseBytes (byte[] buffer, int count, bool discontinuity, bool lastPacket)
    {
        this.lastPacket = lastPacket;
        fileStream.ParseBytes (buffer, 0, count, discontinuity);
    }

    public void Dispose ()
    {
        Dispose (true);
        GC.SuppressFinalize (this);
    }
    public void Dispose(int tt) { 

    }
    /// <summary>
    /// Cleaning up all the native Resource
    /// </summary>
    protected virtual void Dispose (bool disposing)
    {
        if (disposing) {

            if (OutputQueue != null)
                OutputQueue.Stop(true);

            if (outputBuffers != null) {
                foreach (var b in outputBuffers)
                    OutputQueue.FreeBuffer (b.Buffer);

                outputBuffers.Clear ();
                outputBuffers = null;
            }

            if (fileStream != null) {
                fileStream.Close ();
                fileStream = null;
            }

            if (OutputQueue != null) {
                OutputQueue.Dispose ();
                OutputQueue = null;
            }
        }
    }

    /// <summary>
    /// Saving the decoded Packets to our active Buffer, if the Buffer is full queue it into the OutputQueue
    /// and wait until another buffer gets freed up
    /// </summary>
    void AudioPacketDecoded (object sender, PacketReceivedEventArgs args)
    {
        foreach (var p in args.PacketDescriptions) {
            currentByteCount += p.DataByteSize;

            AudioStreamPacketDescription pd = p;

            int left = bufferSize - currentBuffer.CurrentOffset;
            if (left < pd.DataByteSize) {
                EnqueueBuffer ();
                WaitForBuffer ();
            }

            AudioQueue.FillAudioData (currentBuffer.Buffer, currentBuffer.CurrentOffset, args.InputData, (int)pd.StartOffset, pd.DataByteSize);
            // Set new offset for this packet
            pd.StartOffset = currentBuffer.CurrentOffset;
            // Add the packet to our Buffer
            currentBuffer.PacketDescriptions.Add (pd);
            // Add the Size so that we know how much is in the buffer
            currentBuffer.CurrentOffset += pd.DataByteSize;
        }

        if ((fileStream != null && currentByteCount == fileStream.DataByteCount) || lastPacket)
            EnqueueBuffer ();
    }

    /// <summary>
    /// Flush the current buffer and close the whole thing up
    /// </summary>
    public void FlushAndClose ()
    {
        if (OutputQueue != null) {
            EnqueueBuffer ();
            OutputQueue.Flush ();
        }

        Dispose ();
    }

    /// <summary>
    /// Enqueue the active buffer to the OutputQueue
    /// </summary>
    void EnqueueBuffer ()
    {
        currentBuffer.IsInUse = true;
        OutputQueue.EnqueueBuffer (currentBuffer.Buffer, currentBuffer.CurrentOffset, currentBuffer.PacketDescriptions.ToArray ());
        queuedBufferCount++;
        StartQueueIfNeeded ();
    }

    /// <summary>
    /// Wait until a buffer is freed up
    /// </summary>
    void WaitForBuffer ()
    {
        int curIndex = outputBuffers.IndexOf (currentBuffer);
        currentBuffer = outputBuffers [curIndex < outputBuffers.Count - 1 ? curIndex + 1 : 0];

        lock (currentBuffer) {
            while (currentBuffer.IsInUse)
                Monitor.Wait (currentBuffer);
        }
    }

    void StartQueueIfNeeded ()
    {
        if (Started)
            return;

        Play ();
    }

    /// <summary>
    /// When a AudioProperty in the fed packets is found this callback is called
    /// </summary>
    void AudioPropertyFound (object sender, PropertyFoundEventArgs args)
    {
        if (args.Property == AudioFileStreamProperty.ReadyToProducePackets) {
            Started = false;

            if (OutputQueue != null)
                OutputQueue.Dispose ();

            OutputQueue = new OutputAudioQueue (fileStream.StreamBasicDescription);
            if (OutputReady != null)
                OutputReady (OutputQueue);

            currentByteCount = 0;
            OutputQueue.BufferCompleted += HandleBufferCompleted;
            outputBuffers = new List<AudioBuffer> ();

            for (int i = 0; i < MaxBufferCount; i++) {
                IntPtr outBuffer;
                OutputQueue.AllocateBuffer (BufferSize, out outBuffer);
                outputBuffers.Add (new AudioBuffer () {
                    Buffer = outBuffer,
                    PacketDescriptions = new List<AudioStreamPacketDescription> ()
                });
            }

            currentBuffer = outputBuffers.First ();

            OutputQueue.MagicCookie = fileStream.MagicCookie;
        }
    }

    /// <summary>
    /// Is called when a buffer is completly read and can be freed up
    /// </summary>
    void HandleBufferCompleted (object sender, BufferCompletedEventArgs e)
    {
        queuedBufferCount--;
        IntPtr buf = e.IntPtrBuffer;

        foreach (var buffer in outputBuffers) {
            if (buffer.Buffer != buf)
                continue;

            // free Buffer
            buffer.PacketDescriptions.Clear ();
            buffer.CurrentOffset = 0;
            lock (buffer) {
                buffer.IsInUse = false;
                Monitor.Pulse (buffer);
            }
        }

        if (queuedBufferCount == 0 && Finished != null)
            Finished (this, new EventArgs ());
    }
}
}
使用系统;
使用音频工具箱;
使用系统线程;
使用System.Collections.Generic;
使用System.Linq;
名称空间SecondoSenso
{
/// 
///将所有设置保存在一起的AudioBuffer的类
/// 
内部类音频缓冲区
{
公共IntPtr缓冲区{get;set;}
公共列表包描述{get;set;}
public int CurrentOffset{get;set;}
公共布尔值为{get;set;}
}
/// 
///包装OutputQueue和AudioFileStream,以允许各种文件类型的流
/// 
公共类StreamingPlayback:IDisposable
{
public bool boolDispose=false;
公共事件事件处理程序已完成;
公共事件行动输出;
//音频工具箱解码器
音频文件流;
int bufferSize=128*256;
列出输出缓冲区;
音频缓冲器;
//最大缓冲区
int maxBufferCount=4;
//跟踪所有排队的缓冲区,以便我们知道播放已完成
int queuedBufferCount=0;
//当前文件流位置-如果我们不跟踪,我们不知道何时推送最后一个未完成的缓冲区
长currentByteCount=0;
//用于触发最后一个缓冲区的转储。
bool-lastpack;
公共输出队列;
公共bool已启动{get;private set;}
公众浮存量{
得到{
返回OutputQueue.Volume;
}
设置{
OutputQueue.Volume=值;
}
}
/// 
///定义搜索缓冲区的大小,当使用较慢的源时,使用缓冲区大小较低的更多缓冲区
/// 
公共int缓冲区大小{
得到{
返回缓冲区大小;
}
设置{
缓冲区大小=值;
}
}
/// 
///定义要使用的最大缓冲区数,只有在调用重置或
///StreamingPlayback是新实例化的
/// 
公共整数MaxBufferCount{
得到{
返回maxBufferCount;
}
设置{
maxBufferCount=值;
}
}
public StreamingPlayback():这个(AudioFileType.MP3)
{
}
公共流媒体播放(AudioFileType)
{
fileStream=新的音频fileStream(类型);
fileStream.PacketDecoded+=音频包解码;
fileStream.PropertyFound+=AudioPropertyFound;
}
公共无效重置()
{
if(fileStream!=null){
Close();
fileStream=新的音频文件流(AudioFileType.MP3);
currentByteCount=0;
fileStream.PacketDecoded+=音频包解码;
fileStream.PropertyFound+=AudioPropertyFound;
}
}
public void ResetOutputQueue()
{
if(OutputQueue!=null){
OutputQueue.Stop(true);
Reset();
foreach(输出缓冲区中的音频缓冲区buf){
buf.PacketDescriptions.Clear();
OutputQueue.FreeBuffer(buf.Buffer);
}
outputBuffers=null;
Dispose();
}
}
/// 
///停止输出队列
/// 
公共空白暂停()
{
Pause();
开始=错误;
}
/// 
///启动输出队列
/// 
公共虚空游戏()
{
OutputQueue.Start();
开始=真;
}
/// 
///Main方法要启动流,只需将字节发送到此方法
/// 
public void ParseBytes(字节[]缓冲区、整数计数、bool不连续性、bool lastPacket)
{
this.lastPacket=lastPacket;
fileStream.ParseBytes(缓冲区、0、计数、不连续);
}
公共空间处置()
{
处置(真实);
GC.1(本);
}
公共无效处置(int tt){
}
/// 
///清理所有本机资源
/// 
受保护的虚拟void Dispose(bool disposing)
{
如果(处置){
if(OutputQueue!=null)
OutputQueue.Stop(true);
如果(outputBuffers!=null){
foreach(outputBuffers中的变量b)
OutputQueue.FreeBuffer(b.Buffer);
Clear();
outputBuffers=null;
}
if(fileStream!=null){
Close();
fileStream=null;
}
if(OutputQueue!=null){
Dispose();
OutputQueue=null;
}
}
}
/// 
///将解码的数据包保存到活动缓冲区,如果缓冲区已满,则将其排入OutputQueue
///并等待另一个缓冲区释放
/// 
void AudioPacketDecoded(对象发送方,PacketReceivedEventArgs参数)
{
foreach(args.PacketDescriptions中的变量p){
currentByteCount+=p.DataByteSize;
AudioStreamPacketDescription pd=p;
int left=bufferSize-currentBuffer.CurrentOffset;
if(左NSError sessionError = null;
                AVAudioSession.SharedInstance().SetCategory(AVAudioSession.CategoryAmbient, out sessionError);

AVAudioSession.SharedInstance().SetActive(true, out sessionError);