Search code examples
pythontwitter-bootstrap-3jinja2pyramidmongoengine

Stream Video From Gridfs using Python Pyramid and Mongoengine


I'm fairly certain that I do not fully understand the mechanisms at play here, but I'm attempting to display video content by streaming data from GridFS with the Pyramid framework, stored using Mongoengine. Unfortunately, my page can't find the content.

Jinja2:

<div align="center" class="embed-responsive embed-responsive-16by9">
  <video class="embed-responsive-item" controls>
    {% if board.video %}                    
      <source src="{{ request.route_url('boards_video', name=board.name, videoname=board.video.filename) }}" type="video/*">
      Your browser does not support the video tag.  And that makes me sad.
    {% else %}
      <source src="#" type="video/*">
    {% endif %}
  </video>
</div>            

View Code:

@view_config(route_name="boards_video")
  def boards_video(request):            
    from .models import Board
    name = request.matchdict["name"]
    board = Board.objects("name"=name).first().get()
    response = Response(content_type=board.video.content_type)
    response.content_length = board.video.get().length
    response.app_iter = FileIter(board.video)
    return response

Route:

config.add_route("boards_video", "/boards/{name}/videos/{videoname}")

Model:

class Board(document.Document):
    name = fields.StringField(required=True)
    video = fields.FileField()

The URL is being generated when I inspect the source generated by jinja2, but the resulting page video content displays "No video with supported format and MIME type found." What is the proper method for accomplishing this?


Solution

  • Well as I said, this comes down to my lack of understanding of the mechanisms at play. The problem was indeed the HTML.

    The use of the asterisk in the type attribute is an invalid value. Instead, the line should look like this:

    <source src="{{ request.route_url('boards_video', name=board.name, videoname=board.video.filename) }}" type="video/mp4">
    

    My particular use case is attempting to play an mp4, so I have to be explicit. It appears that the browser (in my initial test case, Firefox) is able to determine the value by just removing the type attribute altogether:

    <source src="{{ request.route_url('boards_video', name=board.name, videoname=board.video.filename) }}">
    

    I suppose it's always better to be explicit to ensure that errors are minimized.

    For more info:

    http://www.w3schools.com/html/html5_video.asp