diff --git a/sphinxcontrib/video.py b/sphinxcontrib/video.py
index 6e176cd..560f0b8 100644
--- a/sphinxcontrib/video.py
+++ b/sphinxcontrib/video.py
@@ -1,13 +1,14 @@
"""Video extention to embed video in a html sphinx output."""
+import urllib.parse
from pathlib import Path
from typing import Any, Dict, List, Tuple
-from urllib.parse import urlparse
from docutils import nodes
from docutils.parsers.rst import directives
from sphinx.application import Sphinx
from sphinx.environment import BuildEnvironment
+from sphinx.transforms.post_transforms import SphinxPostTransform
from sphinx.util import logging
from sphinx.util.docutils import SphinxDirective, SphinxTranslator
from sphinx.writers.html import HTMLTranslator
@@ -39,7 +40,7 @@
"List of the supported options attributes"
-def get_video(src: str, env: BuildEnvironment) -> Tuple[str, str]:
+def get_video(src: str, env: BuildEnvironment) -> Tuple[str, str, bool]:
"""Return video and suffix.
Load the video to the static directory if necessary and process the suffix. Raise a warning if not supported but do not stop the computation.
@@ -49,11 +50,8 @@ def get_video(src: str, env: BuildEnvironment) -> Tuple[str, str]:
env: the build environment
Returns:
- the src file, the extention suffix
+ The src file, the extension suffix, whether the file is remote
"""
- if not bool(urlparse(src).netloc):
- env.images.add_file("", src)
-
suffix = Path(src).suffix
if suffix not in SUPPORTED_MIME_TYPES:
logger.warning(
@@ -61,7 +59,16 @@ def get_video(src: str, env: BuildEnvironment) -> Tuple[str, str]:
)
type = SUPPORTED_MIME_TYPES.get(suffix, "")
- return (src, type)
+ is_remote = bool(urllib.parse.urlparse(src).netloc)
+ if not is_remote:
+ # Map video paths to unique names (so that they can be put into a single
+ # directory). This copies what is done for images by the process_docs method of
+ # sphinx.environment.collectors.asset.ImageCollector.
+ src, fullpath = env.relfn2path(src, env.docname)
+ env.note_dependency(fullpath)
+ env.images.add_file(env.docname, src)
+
+ return (src, type, is_remote)
class video_node(nodes.General, nodes.Element):
@@ -120,12 +127,11 @@ def run(self) -> List[video_node]:
preload = "auto"
# add the primary video files as images in the builder
- primary_src = get_video(self.arguments[0], env)
+ sources = [get_video(self.arguments[0], env)]
# add the secondary video files as images in the builder if necessary
- secondary_src = None
if len(self.arguments) == 2:
- secondary_src = get_video(self.arguments[1], env)
+ sources.append(get_video(self.arguments[1], env))
elif env.config.video_enforce_extra_source is True:
logger.warning(
f'A secondary source should be provided for "{self.arguments[0]}"'
@@ -133,8 +139,7 @@ def run(self) -> List[video_node]:
return [
video_node(
- primary_src=primary_src,
- secondary_src=secondary_src,
+ sources=sources,
alt=self.options.get("alt", ""),
autoplay="autoplay" in self.options,
controls="nocontrols" not in self.options,
@@ -149,6 +154,34 @@ def run(self) -> List[video_node]:
]
+class VideoPostTransform(SphinxPostTransform):
+ """Ensure video files are copied to build directory.
+
+ This copies what is done for images in the post_process_image method of
+ sphinx.builders.Builder, except as a Transform since we can't hook into that method
+ directly.
+ """
+
+ default_priority = 200
+
+ def run(self):
+ """Add video files to Builder's image tracking.
+
+ Doing so ensures that the builder copies the files to the output directory.
+ """
+ # TODO: This check can be removed when the minimum supported docutils version
+ # is docutils>=0.18.1.
+ traverse_or_findall = (
+ self.document.findall
+ if hasattr(self.document, "findall")
+ else self.document.traverse
+ )
+ for node in traverse_or_findall(video_node):
+ for src, _, is_remote in node["sources"]:
+ if not is_remote:
+ self.app.builder.images[src] = self.env.images[src][1]
+
+
def visit_video_node_html(translator: HTMLTranslator, node: video_node) -> None:
"""Entry point of the html video node."""
# start the video block
@@ -158,10 +191,16 @@ def visit_video_node_html(translator: HTMLTranslator, node: video_node) -> None:
html: str = f"
diff --git a/tests/test_build/video_options.html b/tests/test_build/video_options.html
index f64ff59..522f3b2 100644
--- a/tests/test_build/video_options.html
+++ b/tests/test_build/video_options.html
@@ -1,4 +1,4 @@
-
+
You cannot display videos
-
\ No newline at end of file
+
diff --git a/tests/test_build/video_secondary.html b/tests/test_build/video_secondary.html
index 1354273..43cf07a 100644
--- a/tests/test_build/video_secondary.html
+++ b/tests/test_build/video_secondary.html
@@ -1,4 +1,4 @@
-
-
-
\ No newline at end of file
+
+
+
diff --git a/tests/test_build/video_wrong_format.html b/tests/test_build/video_wrong_format.html
index f25853b..79b7fe3 100644
--- a/tests/test_build/video_wrong_format.html
+++ b/tests/test_build/video_wrong_format.html
@@ -1,3 +1,3 @@
-
-
\ No newline at end of file
+
+