I looked into this issue. Fundamentally video on DoubleClick is served from a different location than images, scripts, and stylesheets. On a typical HTML5 ad, they will scan the HTML and make replacements to this new URL. However, Hype’s structure is sufficiently opaque and it cannot do the replacement. Instead Hype looks for the video in a path relative to the .hyperesources folder and then gets a 404 from DoubleClick.
The good news is that Google’s JavaScript Enabler API has a way to get the correct path given the original path that Hype expects. While the best solution would be better support for this within Hype, with a bit of JavaScript you can get videos working in DoubleClick.
The way I accomplished this myself was that I added a global listener for the HypeSceneLoad event. When this is fired, I scan through the scene and replace any video source element src attributes with the one provided from Enabler.
So here’s the code that I added to the Head HTML of my document for the video to be displayed within DoubleClick’s preview:
<script src="https://s0.2mdn.net/ads/studio/Enabler.js"></script>
<script type="text/javascript">
var clickTag = "http://google.com";
</script>
<script>
if (!Enabler.isInitialized()) {
Enabler.addEventListener(
studio.events.StudioEvent.INIT,
enablerInitialized);
} else {
enablerInitialized();
}
function enablerInitialized() {
// Enabler initialized.
// In App ads are rendered offscreen so animation should wait for
// the visible event. These are simulated with delays in the local
// environment.
if (!Enabler.isVisible()) {
Enabler.addEventListener(
studio.events.StudioEvent.VISIBLE,
adVisible);
} else {
adVisible();
}
}
function adVisible() {
// do not try to load a scene if the Hype document isn't loaded
if(window.HYPE == null || HYPE.documents == null) {
return;
}
// find the document and load the first scene now
for(var documentName in HYPE.documents) {
if(HYPE.documents.hasOwnProperty(documentName) == false) {
continue;
}
var hypeDocument = HYPE.documents[documentName];
if(hypeDocument.sceneNames().length <= 0) {
continue;
}
hypeDocument.showSceneNamed(hypeDocument.sceneNames()[0]);
}
}
</script>
<script>
// do not show a scene until the Enabler is loaded
function documentLoadCallback(hypeDocument, element, event) {
if(window["Enabler"] == null || Enabler.isVisible() == false) {
return false;
}
return true;
}
// on scene load, replace any relative video source URLs with the Enabler's absolute URL
function sceneLoadCallback(hypeDocument, element, event) {
// only look in the current scene
var sceneElement = currentHypeSceneElement(hypeDocument);
if(sceneElement == null) {
return;
}
// replace each source
var sourceElements = document.getElementsByTagName("source");
for(var i = 0; i < sourceElements.length; i++) {
var sourceElement = sourceElements[i];
// sanity checks
if(sourceElement.parentElement == null || sourceElement.parentElement.tagName.toLowerCase() != "video" || sourceElement.getAttribute("src").length == 0) {
continue;
}
// find the Enabler URL
var videoURL = Enabler.getUrl(sourceElement.getAttribute("src"));
// do the replacement
sourceElement.setAttribute("src", videoURL);
}
}
// utility function to get the current scene - unsupported and may change in the future
function currentHypeSceneElement(hypeDocument) {
var documentElement = document.getElementById(hypeDocument.documentId());
var hypeSceneElements = documentElement.getElementsByClassName("HYPE_scene");
for(var i = 0; i < hypeSceneElements.length; i++) {
if(hypeSceneElements[i].style["display"] == "block") {
return hypeSceneElements[i];
}
}
return null;
}
// setup event listeners to listen for document and scene loads
if("HYPE_eventListeners" in window === false) {
window.HYPE_eventListeners = Array();
}
window.HYPE_eventListeners.push({"type":"HypeDocumentLoad", "callback":documentLoadCallback});
window.HYPE_eventListeners.push({"type":"HypeSceneLoad", "callback":sceneLoadCallback});
</script>
I’d generally call this “unsupported” since it relies on a lot of details on the Hype runtime and how we even place videos in the scene. But it will work for 3.0.
We’ve been getting a lot more requests from the Ad world, so I’d definitely like to improve support for exporting to DoubleClick and other advertising platforms. If you’re working with one, feel free to get in touch because we’d like to hear more about your needs!