Quantcast
Channel: Recent Threads — Xamarin Community Forums
Viewing all articles
Browse latest Browse all 204402

Xamarin.Forms Shoutcast CrossPlatform

$
0
0

I am new in Xamarin.Forms and I am working on a ShoutCast Streamer. I create a Class called ShoutCastStream with the code below :
using System;
using System.Text;
using System.IO;
using System.Net;
using System.Text.RegularExpressions;

#if XAM_ANDROID || XAM_IOS
/// <summary>
/// Provides the functionality to receive a shoutcast media stream
/// </summary>
public class ShoutcastStream : Stream
{
    private int metaInt;
    private int receivedBytes;
    private Stream netStream;
    private bool connected = false;

private string streamTitle;

/// <summary>
/// Is fired, when a new StreamTitle is received
/// </summary>
public event EventHandler StreamTitleChanged;

/// <summary>
/// Creates a new ShoutcastStream and connects to the specified Url
/// </summary>
/// <param name="url">Url of the Shoutcast stream</param>
public ShoutcastStream(string url)
{
    HttpWebResponse response;

    HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
    request.Headers.Clear();
    request.Headers.Add("Icy-MetaData", "1");
    request.KeepAlive = false;
    request.UserAgent = "VLC media player";

    response = (HttpWebResponse)request.GetResponse();

    metaInt = int.Parse(response.Headers["Icy-MetaInt"]);
    receivedBytes = 0;

    netStream = response.GetResponseStream();

    connected = true;
}

/// <summary>
/// Parses the received Meta Info
/// </summary>
/// <param name="metaInfo"></param>
private void ParseMetaInfo(byte[] metaInfo)
{
    string metaString = Encoding.ASCII.GetString(metaInfo);

    string newStreamTitle = Regex.Match(metaString, "(StreamTitle=')(.*)(';StreamUrl)").Groups[2].Value.Trim();
    if (!newStreamTitle.Equals(streamTitle))
    {
        streamTitle = newStreamTitle;
        OnStreamTitleChanged();
    }
}

/// <summary>
/// Fires the StreamTitleChanged event
/// </summary>
protected virtual void OnStreamTitleChanged()
{
    if (StreamTitleChanged != null)
        StreamTitleChanged(this, EventArgs.Empty);
}

/// <summary>
/// Gets a value that indicates whether the ShoutcastStream supports reading.
/// </summary>
public override bool CanRead
{
    get { return connected; }
}

/// <summary>
/// Gets a value that indicates whether the ShoutcastStream supports seeking.
/// This property will always be false.
/// </summary>
public override bool CanSeek
{
    get { return false; }
}

/// <summary>
/// Gets a value that indicates whether the ShoutcastStream supports writing.
/// This property will always be false.
/// </summary>
public override bool CanWrite
{
    get { return false; }
}

/// <summary>
/// Gets the title of the stream
/// </summary>
public string StreamTitle
{
    get { return streamTitle; }
}

/// <summary>
/// Flushes data from the stream.
/// This method is currently not supported
/// </summary>
public override void Flush()
{
    connected = false;
    netStream.Close();
    return;
}

/// <summary>
/// Gets the length of the data available on the Stream.
/// This property is not currently supported and always thows a <see cref="NotSupportedException"/>.
/// </summary>
public override long Length
{
    get { throw new NotSupportedException(); }
}

/// <summary>
/// Gets or sets the current position in the stream.
/// This property is not currently supported and always thows a <see cref="NotSupportedException"/>.
/// </summary>
public override long Position
{
    get
    {
        throw new NotSupportedException();
    }
    set
    {
        throw new NotSupportedException();
    }
}

/// <summary>
/// Reads data from the ShoutcastStream.
/// </summary>
/// <param name="buffer">An array of bytes to store the received data from the ShoutcastStream.</param>
/// <param name="offset">The location in the buffer to begin storing the data to.</param>
/// <param name="count">The number of bytes to read from the ShoutcastStream.</param>
/// <returns>The number of bytes read from the ShoutcastStream.</returns>
public override int Read(byte[] buffer, int offset, int count)
{
    try
    {
        if (receivedBytes == metaInt)
        {
            int metaLen = netStream.ReadByte();
            if (metaLen > 0)
            {
                byte[] metaInfo = new byte[metaLen * 16];
                int len = 0;
                while ((len += netStream.Read(metaInfo, len, metaInfo.Length - len)) < metaInfo.Length) ;
                ParseMetaInfo(metaInfo);
            }
            receivedBytes = 0;
        }

        int bytesLeft = ((metaInt - receivedBytes) > count) ? count : (metaInt - receivedBytes);
        int result = netStream.Read(buffer, offset, bytesLeft);
        receivedBytes += result;
        return result;
    }
    catch (Exception e)
    {
        connected = false;
        Console.WriteLine(e.Message);
        return -1;
    }
}
/// <summary>
/// Closes the ShoutcastStream.
/// </summary>
public override void Close()
{
    connected = false;
    netStream.Close();
}
/// <summary>
/// Sets the current position of the stream to the given value.
/// This Method is not currently supported and always throws a <see cref="NotSupportedException"/>.
/// </summary>
/// <param name="offset"></param>
/// <param name="origin"></param>
/// <returns></returns>
public override long Seek(long offset, SeekOrigin origin)
{
    throw new NotSupportedException();
}

/// <summary>
/// Sets the length of the stream.
/// This Method always throws a <see cref="NotSupportedException"/>.
/// </summary>
/// <param name="value"></param>
public override void SetLength(long value)
{
    throw new NotSupportedException();
}

/// <summary>
/// Writes data to the ShoutcastStream.
/// This method is not currently supported and always throws a <see cref="NotSupportedException"/>.
/// </summary>
/// <param name="buffer"></param>
/// <param name="offset"></param>
/// <param name="count"></param>
public override void Write(byte[] buffer, int offset, int count)
{
    throw new NotSupportedException();
}
}
#endif

Then I used a NuGet called SimpleAudioPlayer to stream this source in this way .
ISimpleAudioPlayer player = Plugin.SimpleAudioPlayer.CrossSimpleAudioPlayer.Current;
var shoutcast = new ShoutcastStream("https://stream2.rjvnlive.com/");
var res = player.Load(shoutcast);
player.Play();
shoutcast.StreamTitleChanged += Shoutcast_StreamTitleChanged;

But unfortunately unable to play this stream. Is there any way to play this Stream implemented in ShoutcastStream class for Xamarin.Forms ?


Viewing all articles
Browse latest Browse all 204402

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>