diff --git a/__tests__/integration/mirador/video.html b/__tests__/integration/mirador/video.html
index 45c8db36dbbbd11ad70e73f814a55bfcf9eecf03..f245fb4c2d21320e5958cf36ae37082ed5ad85a8 100644
--- a/__tests__/integration/mirador/video.html
+++ b/__tests__/integration/mirador/video.html
@@ -16,11 +16,12 @@
        windows: [
          {
            manifestId: 'https://preview.iiif.io/cookbook/master/recipe/0003-mvm-video/manifest.json',
-           view: 'av'
          },
          {
            manifestId: 'https://preview.iiif.io/cookbook/0026_0064_0065-opera-recipes/recipe/0064-opera-one-canvas/manifest.json',
-           view: 'av'
+         },
+         {
+           manifestId: 'https://iiif.io/api/cookbook/recipe/0014-accompanyingcanvas/manifest.json'
          }
       ],
      });
diff --git a/src/components/AVViewer.js b/src/components/AVViewer.js
deleted file mode 100644
index d06c1cfa06a4e2ee8e67fa9a3f8fefc7d1cf9338..0000000000000000000000000000000000000000
--- a/src/components/AVViewer.js
+++ /dev/null
@@ -1,23 +0,0 @@
-import React, { Component } from 'react';
-import PropTypes from 'prop-types';
-
-/** */
-export class AVViewer extends Component {
-  /** */
-  render() {
-    const { currentCanvases } = this.props;
-    const video = currentCanvases[0].getContent()[0].getBody()[0];
-    return (
-      <div style={{ display: 'flex', 'alignItems': 'center' }}>
-        <video controls>
-          <source src={video.id} type={video.format} />
-        </video>
-      </div>
-    );
-  }
-}
-
-AVViewer.propTypes = {
-  currentCanvases: PropTypes.array.isRequired, // eslint-disable-line react/forbid-prop-types
-  windowId: PropTypes.string.isRequired,
-};
diff --git a/src/components/AudioViewer.js b/src/components/AudioViewer.js
new file mode 100644
index 0000000000000000000000000000000000000000..9c5d6c69c51fc8a8944881f33d5421b7eefafac3
--- /dev/null
+++ b/src/components/AudioViewer.js
@@ -0,0 +1,27 @@
+import React, { Component } from 'react';
+import PropTypes from 'prop-types';
+
+/** */
+export class AudioViewer extends Component {
+  /* eslint-disable jsx-a11y/media-has-caption */
+  /** */
+  render() {
+    const { classes, audioResources } = this.props;
+    const audio = audioResources && audioResources[0];
+    if (!audio) return <></>;
+
+    return (
+      <div className={classes.container}>
+        <audio controls className={classes.audio}>
+          <source src={audio.id} type={audio.getFormat()} />
+        </audio>
+      </div>
+    );
+  }
+  /* eslint-enable jsx-a11y/media-has-caption */
+}
+
+AudioViewer.propTypes = {
+  audioResources: PropTypes.arrayOf(PropTypes.object).isRequired,
+  classes: PropTypes.objectOf(PropTypes.string).isRequired,
+};
diff --git a/src/components/PrimaryWindow.js b/src/components/PrimaryWindow.js
index df0e9e89ac23a8ec42aa5479329cd139e5b893dd..97728d88907f03a67e4d534209d92601db75ce71 100644
--- a/src/components/PrimaryWindow.js
+++ b/src/components/PrimaryWindow.js
@@ -6,28 +6,29 @@ import CompanionArea from '../containers/CompanionArea';
 import CollectionDialog from '../containers/CollectionDialog';
 import ns from '../config/css-ns';
 
+const AudioViewer = lazy(() => import('../containers/AudioViewer'));
 const GalleryView = lazy(() => import('../containers/GalleryView'));
 const SelectCollection = lazy(() => import('../containers/SelectCollection'));
 const WindowViewer = lazy(() => import('../containers/WindowViewer'));
-const AVViewer = lazy(() => import('../containers/AVViewer'));
+const VideoViewer = lazy(() => import('../containers/VideoViewer'));
 
 GalleryView.displayName = 'GalleryView';
 SelectCollection.displayName = 'SelectCollection';
 WindowViewer.displayName = 'WindowViewer';
 
 /**
- * WindowMiddleContent - component that renders the "middle" area of the
- * Mirador Window
+ * PrimaryWindow - component that renders the primary content of a Mirador
+ * window. Right now this differentiates between a Image, Video, or Audio viewer.
  */
 export class PrimaryWindow extends Component {
   /**
-   * renderViewer
+   * renderViewer - logic used to determine what type of view to show
    *
    * @return {(String|null)}
    */
   renderViewer() {
     const {
-      isCollection, isCollectionDialogVisible, isFetching, view, windowId,
+      audioResources, isCollection, isCollectionDialogVisible, isFetching, videoResources, view, windowId,
     } = this.props;
     if (isCollection) {
       return (
@@ -47,9 +48,16 @@ export class PrimaryWindow extends Component {
           />
         );
       }
-      if (view === 'av') {
+      if (videoResources.length > 0) {
         return (
-          <AVViewer
+          <VideoViewer
+            windowId={windowId}
+          />
+        );
+      }
+      if (audioResources.length > 0) {
+        return (
+          <AudioViewer
             windowId={windowId}
           />
         );
@@ -81,10 +89,12 @@ export class PrimaryWindow extends Component {
 }
 
 PrimaryWindow.propTypes = {
+  audioResources: PropTypes.arrayOf(PropTypes.object).isRequired,
   classes: PropTypes.objectOf(PropTypes.string).isRequired,
   isCollection: PropTypes.bool,
   isCollectionDialogVisible: PropTypes.bool,
   isFetching: PropTypes.bool,
+  videoResources: PropTypes.arrayOf(PropTypes.object).isRequired,
   view: PropTypes.string,
   windowId: PropTypes.string.isRequired,
 };
diff --git a/src/components/VideoViewer.js b/src/components/VideoViewer.js
new file mode 100644
index 0000000000000000000000000000000000000000..7a31969faaf5c1c7547d97a13af4d5cdbe8c089d
--- /dev/null
+++ b/src/components/VideoViewer.js
@@ -0,0 +1,27 @@
+import React, { Component } from 'react';
+import PropTypes from 'prop-types';
+
+/** */
+export class VideoViewer extends Component {
+  /* eslint-disable jsx-a11y/media-has-caption */
+  /** */
+  render() {
+    const { classes, videoResources } = this.props;
+    const video = videoResources && videoResources[0];
+    if (!video) return <></>;
+
+    return (
+      <div className={classes.container}>
+        <video controls className={classes.video}>
+          <source src={video.id} type={video.getFormat()} />
+        </video>
+      </div>
+    );
+  }
+  /* eslint-enable jsx-a11y/media-has-caption */
+}
+
+VideoViewer.propTypes = {
+  classes: PropTypes.objectOf(PropTypes.string).isRequired,
+  videoResources: PropTypes.arrayOf(PropTypes.object).isRequired,
+};
diff --git a/src/containers/AVViewer.js b/src/containers/AVViewer.js
deleted file mode 100644
index b6e452ef3a26f5fcb633b3fccc4f24fad51ab1a7..0000000000000000000000000000000000000000
--- a/src/containers/AVViewer.js
+++ /dev/null
@@ -1,21 +0,0 @@
-import { connect } from 'react-redux';
-import { compose } from 'redux';
-import { withTranslation } from 'react-i18next';
-import { withPlugins } from '../extend/withPlugins';
-import { AVViewer } from '../components/AVViewer';
-import { getVisibleCanvases } from '../state/selectors';
-
-/** */
-const mapStateToProps = (state, { windowId }) => (
-  {
-    currentCanvases: getVisibleCanvases(state, { windowId }) || [],
-  }
-);
-
-const enhance = compose(
-  withTranslation(),
-  connect(mapStateToProps, null),
-  withPlugins('AVViewer'),
-);
-
-export default enhance(AVViewer);
diff --git a/src/containers/AudioViewer.js b/src/containers/AudioViewer.js
new file mode 100644
index 0000000000000000000000000000000000000000..65d198f5ad1be542536bb025064a6c25810c418e
--- /dev/null
+++ b/src/containers/AudioViewer.js
@@ -0,0 +1,35 @@
+import { connect } from 'react-redux';
+import { compose } from 'redux';
+import { withTranslation } from 'react-i18next';
+import { withStyles } from '@material-ui/core';
+import { withPlugins } from '../extend/withPlugins';
+import { AudioViewer } from '../components/AudioViewer';
+import { getVisibleCanvasAudioResources } from '../state/selectors';
+
+/** */
+const mapStateToProps = (state, { windowId }) => (
+  {
+    audioResources: getVisibleCanvasAudioResources(state, { windowId }) || [],
+  }
+);
+
+/** */
+const styles = () => ({
+  audio: {
+    width: '100%',
+  },
+  container: {
+    alignItems: 'center',
+    display: 'flex',
+    width: '100%',
+  },
+});
+
+const enhance = compose(
+  withTranslation(),
+  withStyles(styles),
+  connect(mapStateToProps, null),
+  withPlugins('AudioViewer'),
+);
+
+export default enhance(AudioViewer);
diff --git a/src/containers/PrimaryWindow.js b/src/containers/PrimaryWindow.js
index 35a86dfa27dd2de03e166223ef6de34a649091e4..336894235f31a71867a2e77da22347d9099c7909 100644
--- a/src/containers/PrimaryWindow.js
+++ b/src/containers/PrimaryWindow.js
@@ -2,15 +2,19 @@ import { compose } from 'redux';
 import { connect } from 'react-redux';
 import { withStyles } from '@material-ui/core/styles';
 import { withPlugins } from '../extend/withPlugins';
-import { getManifestoInstance, getWindow } from '../state/selectors';
+import {
+  getManifestoInstance, getVisibleCanvasAudioResources, getVisibleCanvasVideoResources, getWindow,
+} from '../state/selectors';
 import { PrimaryWindow } from '../components/PrimaryWindow';
 
 /** */
 const mapStateToProps = (state, { windowId }) => {
   const manifestoInstance = getManifestoInstance(state, { windowId });
   return {
+    audioResources: getVisibleCanvasAudioResources(state, { windowId }) || [],
     isCollection: manifestoInstance && manifestoInstance.isCollection(),
     isCollectionDialogVisible: getWindow(state, { windowId }).collectionDialogOn,
+    videoResources: getVisibleCanvasVideoResources(state, { windowId }) || [],
   };
 };
 
@@ -24,7 +28,7 @@ const styles = {
 
 const enhance = compose(
   withStyles(styles),
-  connect(mapStateToProps),
+  connect(mapStateToProps, null),
   withPlugins('PrimaryWindow'),
 );
 
diff --git a/src/containers/VideoViewer.js b/src/containers/VideoViewer.js
new file mode 100644
index 0000000000000000000000000000000000000000..97f7620362b99368aeea17222afb3dba83437873
--- /dev/null
+++ b/src/containers/VideoViewer.js
@@ -0,0 +1,35 @@
+import { connect } from 'react-redux';
+import { compose } from 'redux';
+import { withTranslation } from 'react-i18next';
+import { withStyles } from '@material-ui/core';
+import { withPlugins } from '../extend/withPlugins';
+import { VideoViewer } from '../components/VideoViewer';
+import { getVisibleCanvasVideoResources } from '../state/selectors';
+
+/** */
+const mapStateToProps = (state, { windowId }) => (
+  {
+    videoResources: getVisibleCanvasVideoResources(state, { windowId }) || [],
+  }
+);
+
+/** */
+const styles = () => ({
+  container: {
+    alignItems: 'center',
+    display: 'flex',
+    width: '100%',
+  },
+  video: {
+    width: '100%',
+  },
+});
+
+const enhance = compose(
+  withTranslation(),
+  withStyles(styles),
+  connect(mapStateToProps, null),
+  withPlugins('VideoViewer'),
+);
+
+export default enhance(VideoViewer);
diff --git a/src/lib/MiradorCanvas.js b/src/lib/MiradorCanvas.js
index ac375b1df8eb054c7b17c3d75a882b6efb279dd3..ebd45f2f5d81cf9b9ada0f663075f23404a765d9 100644
--- a/src/lib/MiradorCanvas.js
+++ b/src/lib/MiradorCanvas.js
@@ -81,6 +81,24 @@ export default class MiradorCanvas {
     }));
   }
 
+  /** */
+  get videoResources() {
+    const resources = flattenDeep([
+      this.canvas.getContent().map(i => i.getBody()),
+    ]);
+
+    return flatten(resources.filter((resource) => resource.getProperty('type') === 'Video'));
+  }
+
+  /** */
+  get audioResources() {
+    const resources = flattenDeep([
+      this.canvas.getContent().map(i => i.getBody()),
+    ]);
+
+    return flatten(resources.filter((resource) => resource.getProperty('type') === 'Sound'));
+  }
+
   /** */
   get resourceAnnotations() {
     return flattenDeep([
diff --git a/src/state/selectors/canvases.js b/src/state/selectors/canvases.js
index 4a3c9924889b25d1caa071bc965ae2a557d018a8..71b3e274e370b82bf10b81ea86e043f4bddf2a85 100644
--- a/src/state/selectors/canvases.js
+++ b/src/state/selectors/canvases.js
@@ -184,6 +184,22 @@ export const getVisibleCanvasNonTiledResources = createSelector(
     .filter(resource => resource.getServices().length < 1),
 );
 
+export const getVisibleCanvasVideoResources = createSelector(
+  [
+    getVisibleCanvases,
+  ],
+  canvases => flatten(canvases
+    .map(canvas => new MiradorCanvas(canvas).videoResources)),
+);
+
+export const getVisibleCanvasAudioResources = createSelector(
+  [
+    getVisibleCanvases,
+  ],
+  canvases => flatten(canvases
+    .map(canvas => new MiradorCanvas(canvas).audioResources)),
+);
+
 export const selectInfoResponse = createSelector(
   [
     (state, { infoId }) => infoId,