<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>xscDevBlog - LastSharp &#38; Co. &#187; streaming</title>
	<atom:link href="http://dev.xscheme.de/tag/streaming/feed/" rel="self" type="application/rss+xml" />
	<link>http://dev.xscheme.de</link>
	<description>Der xscheme-DevelopmentBlog</description>
	<lastBuildDate>Sun, 23 May 2010 11:40:10 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Audiostreaming mit irrKlang (C#)</title>
		<link>http://dev.xscheme.de/2008/08/audiostreaming-mit-irrklang/</link>
		<comments>http://dev.xscheme.de/2008/08/audiostreaming-mit-irrklang/#comments</comments>
		<pubDate>Thu, 14 Aug 2008 05:59:27 +0000</pubDate>
		<dc:creator>xsc</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[audio]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[irrklang]]></category>
		<category><![CDATA[part of lastsharp]]></category>
		<category><![CDATA[streaming]]></category>

		<guid isPermaLink="false">http://dev.xscheme.de/?p=147</guid>
		<description><![CDATA[
Auf der Suche nach einem Ersatz für die DirectX-Wiedergabe in LastSharp bin ich gestern über irrKlang gestolpert. Soweit so gut: plattformunabhängig, einfach zu bedienen, eigentlich alles in Ordnung. Aber dann gab es da doch noch ein größeres Manko, das ich nicht ignorieren konnte: das Streaming von Dateien, die im Internet liegen, ist nicht möglich &#8211; [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.ambiera.com/irrklang/"><img src="http://dev.xscheme.de/wp-content/uploads/2008/08/irrklang_link_big.png" style="margin-bottom: 1em" /></a><br/><br />
Auf der Suche nach einem Ersatz für die DirectX-Wiedergabe in LastSharp bin ich gestern über <a href="http://www.ambiera.com/irrklang/">irrKlang</a> gestolpert. Soweit so gut: plattformunabhängig, einfach zu bedienen, eigentlich alles in Ordnung. Aber dann gab es da doch noch ein größeres Manko, das ich nicht ignorieren konnte: das Streaming von Dateien, die im Internet liegen, ist nicht möglich &#8211; und genau das bräuchte ich aber für LastSharp. Was also machen?</p>
<p><span id="more-147"></span></p>
<p>Über <a href="http://www.ambiera.com/irrklang/docu/index.html#fileOverriding">dieses Tutorial</a> bin ich der Sache näher gekommen: Man muss eine eigene Implementierung des Interfaces <code>IFileFactory</code> erstellen, und &#8211; falls nötig &#8211; eine eigene <code>Stream</code>-Klasse. Und letzteres war durchaus nötig, da mir keine bereitgestellte <code>Stream</code>-Klasse die entsprechenden Möglichkeit der Pufferung eines Audiostreams geboten hat. So ist die Klasse <code>InternetStream</code> geboren worden, die eine Verbindung zu einer Datei im Internet herstellt (mittels HttpWebRequest), und die empfangenen Daten in einer Datei auf der Festplatte speichern kann, auf die ebenso die Möglichkeit gleichzeitigen Zugriffs besteht:</p>
<pre class="c#" name="code">
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Net;
using System.Threading;
using System.Windows.Forms;
using System.Collections;
using IrrKlang;

public class InternetStream : Stream
{
    // =======================================================
    // Buffer-Daten
    private Stream resp = null;
    private string BufferFile = "streaming.mp3";
    private FileStream OutputStream = null;
    private FileStream BufferStream = null;
    private Thread BufferThread = null;
    // =======================================================
    // Konstruktor
    public InternetStream(string uri, string bfile)
    {
        // Dateiname des lokalen Files
        this.BufferFile = bfile;
        // FileStream zum Schreiben öffnen
        if (File.Exists(this.BufferFile)) { try { File.Delete(this.BufferFile); } catch { } }
        this.BufferStream = new FileStream(this.BufferFile, FileMode.OpenOrCreate, FileAccess.Write, FileShare.Read);
        // ResponseStream zum File im Internet
        this.resp = ((HttpWebRequest)WebRequest.Create(uri)).GetResponse().GetResponseStream();
        // Pufferung starten
        this.BufferThread = new Thread(new ThreadStart(this.FillBuffer));
        this.BufferThread.Start();
    }
    // =======================================================
    // Read: wenn zehn mal 0 zurückgegeben wird, werden alle
    // Streams geschlossen und der Thread beendet
    private int ReadTries = 0;
    public override int Read(byte[] array, int offset, int count)
    {
        // Ausgabe-Stream öffnen
        if (this.OutputStream == null) this.OutputStream = new FileStream(this.BufferFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
        try
        {
            // Dem Puffer Zeit geben, Daten zu holen
            while (this.OutputStream.Length == 0) Thread.Sleep(100);
            // Daten lesen
            int s = this.OutputStream.Read(array, offset, count);
            // Wenn 0: ein erfolgloser Versuch mehr
            if (s == 0) this.ReadTries++;
            if (this.ReadTries &gt; 10)
            {
                this.Close();
            }
            //
            return s;
        }
        catch { return 0; }
    }
    // =======================================================
    // Seek
    public override long Seek(long offset, SeekOrigin loc)
    {
        return this.OutputStream.Seek(offset, loc);
    }
    // =======================================================
    // Puffer-Thread
    private void FillBuffer()
    {
        byte[] buffer = new byte[20 * 1024];
        int rd = 0;
        while ((rd = this.resp.Read(buffer, 0, buffer.Length)) &gt; 0)
        {
            this.BufferStream.Write(buffer, 0, rd);
        }
    }
    // =======================================================
    // Schließen
    public override void Close()
    {
        this.OutputStream.Close();
        this.BufferStream.Close();
        this.BufferThread.Abort();
        if (File.Exists(this.BufferFile))
            try { File.Delete(this.BufferFile); }
            catch { }
        base.Close();
    }
    // =======================================================
    // Length
    public override long Length
    {
        get
        {
            if (this.OutputStream == null) return 0;
            else return this.OutputStream.Length;
        }
    }
    // =======================================================
    // Properties: CanRead, CanSeek, CanWrite
    public override bool CanRead
    {
        get { return true; }
    }

    public override bool CanSeek
    {
        get { return true; }
    }

    public override bool CanWrite
    {
        get { return false; }
    }
    // =======================================================
    // restliche Methoden, damit die Stream-Implementierung
    // komplett ist
    public override void Flush()
    {
        this.OutputStream.Flush();
    }

    public override long Position
    {
        get
        {
            return this.OutputStream.Position;
        }
        set
        {
            this.OutputStream.Position = value;
        }
    }

    public override void SetLength(long value)
    {
        this.OutputStream.SetLength(value);
    }

    public override void Write(byte[] buffer, int offset, int count)
    {
        return;
    }
}</pre>
<p>Die entsprechende <code>IFileFactory</code>-Implementation:</p>
<pre class="c#" name="code">
public class StreamFileFactory : IFileFactory
{
    // =====================================
    // Öffne ein File (von Irrklang verwendete Methode)
    public Stream openFile(string filename)
    {
        if (filename.StartsWith("http://"))
        {
            // neuen Starten
            string fn = Application.StartupPath + "/streaming.mp3";
            try
            {
                InternetStream istream = new InternetStream(filename, fn);
                return istream;
            }
            catch { return null; }
        }
        else
        {
            // lokale Datei
            return new FileStream(filename, FileMode.Open, FileAccess.Read);
        }
    }
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://dev.xscheme.de/2008/08/audiostreaming-mit-irrklang/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
