2010-07-31 6 views
0

J'utilise des sockets VB.net pour envoyer un fichier musical d'une instance à une autre. Il enregistre actuellement le fichier, mais je ne veux pas être coincé dans le partage de fichiers, donc je veux le "sauvegarder" dans un tampon, et quand il arrive à un pourcentage particulier transféré, je veux un autre thread pour jouer de la musique fichier, en le supprimant du tampon pendant sa lecture. J'ai le code pour l'envoyer sur le réseau, mais j'ai besoin de savoir comment le garder dans un tampon et ne pas l'enregistrer comme un fichier.Diffusion en continu dans un buffer puis utilisation de données

Merci

Nick

+0

Pourriez-vous poster le code qui reçoit les données? S'il arrive dans un flux, lisez-le dans un MemoryStream. Aussi, lisez-vous continuellement ou juste une chanson à la fois? –

Répondre

2

Supposons que vous obtenez un flux réseau, vous pouvez faire quelque chose comme le code ci-dessous.

Le sous-registre Main() obtient un flux réseau et le lit jusqu'à la fin. Il a passé les octets à la classe PlayBuffer qui ajoute les octets à la fin d'un MemoryStream. Lorsque vous utilisez la méthode Read() sur le PlayBuffer, il lit dès le début et conserve un pointeur vers l'endroit où vous avez lu. Le verrouillage est là pour que vous puissiez écrire et lire dans le flux à partir de threads séparés. Je n'ai pas fourni de code qui utilise Read(). C'est juste pour donner une idée. Si vous obtenez des octets continus, vous pouvez alors allouer un grand buffer et une fois à la fin, vous recommencez à écrire au début (buffer circulaire).

[Modifier - le code modifié pour écrire et lire en même temps]

Je n'ai pas complètement testé le code, mais la classe PlayBuffer hérite d'un cours d'eau et doit être capable de lire et écrire en même temps, tant qu'un thread écrit et que l'autre lit juste.

Friend Class PlayProgram 
    Public Sub Main() 
     Dim playBuffer As New PlayBuffer 
     Dim readData As New Thread(Function 
      Using client As TcpClient = New TcpClient("somehostname", 80) 
       Using networkStream As NetworkStream = client.GetStream 
        Dim readBytes As Integer 
        Dim buffer As Byte() = New Byte(&H1000 - 1) {} 
        Do While (readBytes = networkStream.Read(buffer, 0, buffer.Length) > 0) 
         playBuffer.Write(buffer, 0, readBytes) 
         playBuffer.Flush 
        Loop 
       End Using 
      End Using 
     End Function) 
     readData.Start 
     New SoundPlayer(playBuffer).Play 
     readData.Join 
    End Sub 
End Class 


Friend Class PlayBuffer 
    Inherits Stream 
    Public Sub AppendToBuffer(ByVal buffer As Byte(), ByVal bytesRead As Integer) 
     SyncLock PlayBuffer._lock 
      Me._buffer.Position = Me._buffer.Length 
      Me._buffer.Write(buffer, 0, bytesRead) 
     End SyncLock 
    End Sub 

    Public Overrides Sub Flush() 
     SyncLock PlayBuffer._lock 
      Me._buffer.Flush 
     End SyncLock 
    End Sub 

    Public Overrides Function Read(ByVal internalBuffer As Byte(), ByVal offset As Integer, ByVal count As Integer) As Integer 
     SyncLock PlayBuffer._lock 
      Me._buffer.Position = Me._readPosition 
      Dim bytesRead As Integer = Me._buffer.Read(internalBuffer, 0, internalBuffer.Length) 
      Me._readPosition = (Me._readPosition + bytesRead) 
      Return bytesRead 
     End SyncLock 
    End Function 

    Public Overrides Function Seek(ByVal offset As Long, ByVal origin As SeekOrigin) As Long 
     Throw New NotImplementedException 
    End Function 

    Public Overrides Sub SetLength(ByVal value As Long) 
     Throw New NotImplementedException 
    End Sub 

    Public Overrides Sub Write(ByVal buffer As Byte(), ByVal offset As Integer, ByVal count As Integer) 
     SyncLock PlayBuffer._lock 
      Me._buffer.Position = Me._buffer.Length 
      Me._buffer.Write(buffer, offset, count) 
     End SyncLock 
    End Sub 


    Public Overrides ReadOnly Property CanRead As Boolean 
     Get 
      Return True 
     End Get 
    End Property 

    Public Overrides ReadOnly Property CanSeek As Boolean 
     Get 
      Throw New NotImplementedException 
     End Get 
    End Property 

    Public Overrides ReadOnly Property CanWrite As Boolean 
     Get 
      Return True 
     End Get 
    End Property 

    Public Overrides ReadOnly Property Length As Long 
     Get 
      Return Me._buffer.Length 
     End Get 
    End Property 

    Public Overrides Property Position As Long 
     Get 
      Return Me._readPosition 
     End Get 
     Set(ByVal value As Long) 
      Throw New NotImplementedException 
     End Set 
    End Property 

    Private ReadOnly _buffer As MemoryStream = New MemoryStream 
    Private Shared ReadOnly _lock As Object = New Object 
    Private _readPosition As Long 
End Class 
+0

Mikael, je voudrais juste dire un énorme merci, cela a beaucoup aidé! – Nick

+0

Ceci est nouveau pour moi, pourriez-vous fournir un code qui utilise la fonction de lecture? merci (aussi, c'est juste une chanson à la fois) – Nick

+0

Lire vous donnera un tableau d'octets, donc cela dépend de ce que vous utilisez pour réellement jouer votre audio. http://stackoverflow.com/questions/184683/play-audio-from-a-stream-using-c a un exemple d'utilisation de NAudio pour jouer à partir d'un flux. Si vous l'utilisez, vous pouvez transmettre directement le flux réseau au constructeur de la librairie player. Qu'est-ce que vous utilisez pour lire l'audio? –

Questions connexes