Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Broken pipe during stream

I have a project with Django I am working on where I want to stream some mp3 files.

I have this same issue: Streaming mp3 files with django, read from a page with <audio>

Let me explain: I want stream an ogg with Django, and with an <audio> tag in my html page

I have a url like domain.tld/song/show/X/, where X is the id of my song. I can stream with VLC (directly with the file path), I can stream during test, (I write what I receive and read it with VLC).

But when I open my browser and load my home page domain.tld where I have and <\audio\> balise with url domain.tld/song/show/1/, I get a big broken pipe, as if my client closed the connection.

I read on others post that some problems was resolved when they put server in production. So I push my app on server, use apache, with the django.wgsi like on djangoproject.com.

I am running python 2.7.3 on Debian 7 with Django version 1.5. there my code:

Song/views.py

def playAudioFile(request, pk):
    f = get_stream_song(pk)# return a pipe from pipes.Template
    l = f.read() # the file is an ogg get by pydub.com
    f.close()
    size_read = 550000
    sr = size_read
    while sr == size_read:
        print "rep"
        r = l[:size_read]
        l=l[size_read:]
        sr = len(r)
        yield r
    time.sleep(0.1) 

#url : ~/song/show/X/
#@login_required
def show_song(request, pk):
        return StreamingHttpResponse(playAudioFile(request, pk), mimetype='audio/ogg',)

In my HTML, I just have that:

 <audio controls height="100" width="100" preload="auto">
    <source src="/.../song/show/1/" type="audio/ogg">
    <embed height="50" width="100" src="/.../song/show/1/">
  </audio>

The error looks like:

Traceback (most recent call last):
  File "/usr/lib/python2.7/wsgiref/handlers.py", line 86, in run
    self.finish_response()
  File "/usr/lib/python2.7/wsgiref/handlers.py", line 127, in finish_response
    self.write(data)
  File "/usr/lib/python2.7/wsgiref/handlers.py", line 215, in write
    self._write(data)
  File "/usr/lib/python2.7/socket.py", line 324, in write
    self.flush()
  File "/usr/lib/python2.7/socket.py", line 303, in flush
    self._sock.sendall(view[write_offset:write_offset+buffer_size])
error: [Errno 104] Connection reset by peer
----------------------------------------
Exception happened during processing of request from ('127.0.0.1', 46392)
Traceback (most recent call last):
  File "/usr/lib/python2.7/SocketServer.py", line 593, in process_request_thread
    self.finish_request(request, client_address)
  File "/usr/lib/python2.7/SocketServer.py", line 334, in finish_request
    self.RequestHandlerClass(request, client_address, self)
  File "/home/lumy/SPhoque/SonoPhoque/SoPhoque/local/lib/python2.7/site-packages/django/core/servers/basehttp.py", line 150, in __init__
    super(WSGIRequestHandler, self).__init__(*args, **kwargs)
  File "/usr/lib/python2.7/SocketServer.py", line 651, in __init__
    self.finish()
  File "/usr/lib/python2.7/SocketServer.py", line 704, in finish
    self.wfile.flush()
  File "/usr/lib/python2.7/socket.py", line 303, in flush
    self._sock.sendall(view[write_offset:write_offset+buffer_size])
error: [Errno 32] Broken pipe

I got this twice each time I try to stream.


Edit 15h 29/05:

I did what rahan suggested: Looking at Firebug and Firefox debugger:

The client does:

GET 1   200 OK localhost:8000 537.1KB 4.71s

Headers
Response Headersview source
Date    Wed, 29 May 2013 13:08:54 GMT
Server  WSGIServer/0.1 Python/2.7.3
Content-Type    audio/ogg
Request Headersview source
Host    localhost:8000
User-Agent  Mozilla/5.0 (X11; Linux x86_64; rv:10.0.12) Gecko/20100101 Firefox/10.0.12 Iceweasel/10.0.12
Accept  audio/webm,audio/ogg,audio/wav,audio/*;q=0.9,application/ogg;q=0.7,video/*;q=0.6,*/*;q=0.5
Accept-Language en-us,en;q=0.5
Connection  keep-alive
Range   bytes=0-
Referer http://localhost:8000/

and details say that the total size for all documents is 1 MB (526 KB from cache)

like image 602
Lumy Avatar asked May 29 '13 10:05

Lumy


People also ask

What does NCAT broken pipe mean?

A 'Broken pipe' message happens when you write to a stream where the other end has been closed. In your example, your handle_connection routine reads a single buffer from the client, copies that back to the client, and then returns, which will close the stream.

What is TCP broken pipe?

The broken pipe is a TCP/IP error occurring when you write to a stream where the other end (the peer) has closed the underlying connection. The first write to the closed connection causes the peer to reply with an RST packet indicating that the connection should be terminated immediately.


1 Answers

May be I am crossing your existing solution, i have a suggestion, for mp3 streaming use nginx/apache server, these days there is solution known as sendfile, for example in your case on django view

def send_file_header(server_type):
    header = "X-Sendfile" if server_type == "apache" else "X-Accel-Redirect"
    return header

@login_required
def show_song(request, pk):
    res =  HttpResponse()
    path = "/path/to/secret/x.mp3"
    response[send_file_header('nginx')] = path
    response['Content-Type']= "application/octet-stream"
    response['Content-Disposition'] = "attachment; filename=\"x.mp3\""
    return response
like image 79
Renjith Thankachan Avatar answered Sep 30 '22 15:09

Renjith Thankachan