       </div>
     </div>
 
+  renderFrame: (type, format, src, frame) ->
+    FrameWrapper = @props.frameWrapper
+    <FrameWrapper frame={frame} naturalWidth={@state.frameDimensions[src]?.width} naturalHeight={@state.frameDimensions[src]?.height} workflow={@props.workflow} subject={@props.subject} classification={@props.classification} annotation={@props.annotation}>
+      {switch type
+        when 'image'
+          <img className="subject" src={src} style={SUBJECT_STYLE} onLoad={@handleLoad} />
+        when 'video'
+          <video src={src} type={"#{type}/#{format}"} controls onLoad={@handleLoad}>
+            Your browser does not support the video format. Please upgrade your browser.
+          </video>}
+    </FrameWrapper>
 
   hiddenPreloadedImages: ->
     # Render this to ensure that all a subject's location images are cached and ready to display.

    frame: @props.frame ? 0
    playbackRate: 1
    frameDimensions: {}

  componentDidMount: ->
    @refs.videoScrubber?.value = 0

    @refs.videoPlayer?.playbackRate = @state.playbackRate

  render: ->
    mainDisplay = ''
    if @state.inFlipbookMode
      {type, format, src} = getSubjectLocation @props.subject, @state.frame
      mainDisplay = @renderFrame type, format, src, @state.frame
    else
      mainDisplay = for frame of @props.subject.locations
        {type, format, src} = getSubjectLocation @props.subject, frame
        @renderFrame type, format, src, frame

    tools = switch type
      when 'image'
        if not @state.inFlipbookMode or @props.subject?.locations.length < 2 or subjectHasMixedLocationTypes @props.subject
          null
        else
          <span className="subject-frame-play-controls">
