How to embed video like [img[xxx]]

Oh, how can I forget the transclude…

Sometimes I use {{xxx.png}} too.

1 Like

Oh, no, video embedding suffers from " ResizeObserver loop limit exceeded"

https://groups.google.com/g/tiddlywiki/c/vXVLQD58yPQ/m/0f8vPFPtGwAJ

The solution there is remove the controls attribute from <video> tag, but when using transclusion, there is no way to access the video tag…

1 Like

i’m using a slightly different solution because i couldn’t get anything else to work (does not work well in all browsers, issues with autoplay etc so i normally use a streams node to hide it until needed); suggestions welcomed!

<iframe width="277px" height="600px" src="video/20210809 split screen iphone input.mp4" frameborder="0" type="video/mp4" controls></iframe>

1 Like

Side comment. Iframes, in general, are fraught. I so wish they were simpler to get to work well, reliably. My experience is they are bit like jujitsu to get to work reliably.

I do think, regarding the OP, it is worth differentiating what issues are intrinsic to iframe stuff in general and which might be TW specific.

There is no doubt that iframe use, since the lockdown of browsers due to security concerns (sometimes verging on paranoia), has got complicated. Personally it has made my life more difficult.

Just a side comment
TT

This somehow works, but in a weird way:

<iframe height="400px" src="hypernote-meme-map.mp4" frameborder="0" type="video/mp4" controls></iframe>

It even involve the tiddler title and wiki title…

It is difficult to know without a working link :frowning:

Hi linonetwo,

This one works for me;

<$wikify name=URI text="https://raw.githubusercontent.com/linonetwo/wiki/master/tiddlers/hypernote-meme-map.mp4">
<video controls autoplay loop style="width:320px; object-fit:contain;" src=<<URI>>>
</video>
</$wikify>

The original came from somewhere on the GG forum I think, not my own work, respect to the original author!

如果它不起作用回来,周围有很多视频解决方案。 我正在测试谷歌翻译。 我希望语言是正确的。 最良好的祝愿瓦

1 Like
2 Likes

Here is my most inelegant workaround one year too late. I’m almost ashamed to share this.
If you want a looping autoplaying .mp4 video from video embedded in a binary tiddler in a single file TiddlyWiki this is the only way so far I could make it work.

Use a regular text tiddler and paste the raw base64 encoded video and corresponding markup into the text field. Something like

<video autoplay loop src="data:video/mp4;base64," style="width: 100%; object-fit: contain"></video>

You can obtain the base64 encoded info by first embedding the video directly into TiddlyWiki, then copying the outer html with the browser markup Inspect feature. Then just change the markup for play mode into something that suits your needs like <video autoplay loop >.

Downsides are:

  • It is ugly
  • It’s slow and cumbersome to edit (takes forever to display all that b64 text)
  • Content won’t show up in the regular Insert Image toolbar button (Videos never did either way)
  • Tiddler is not marked as binary data
  • Can’t download binary data through regular method (It does work if you right click the video and choose download)

Advantages:

  • Can be inserted with regular transclusion like {{video tiddler.mp4}}
  • It works, sort of ¯\__(ツ)__/¯
2 Likes

Ok, here’s a slightly little less ugly hack

Override the core tiddler $:/core/modules/parsers/videoparser.js by creating a copy

In the text field add

/*\
title: $:/core/modules/parsers/videoparser.js
type: application/javascript
module-type: parser

The video parser parses a video tiddler into an embeddable HTML element

\*/
(function(){

/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";

var VideoParser = function(type,text,options) {
	var element = {
			type: "element",
			tag: "video",
			attributes: {
				autoplay: {type: "string", value: ""},
				loop: {type: "string", value: ""},
				style: {type: "string", value: "width: 100%; object-fit: contain"}
			}
		},
		src;
	if(options._canonical_uri) {
		element.attributes.src = {type: "string", value: options._canonical_uri};
	} else if(text) {
		element.attributes.src = {type: "string", value: "data:" + type + ";base64," + text};
	}
	this.tree = [element];
	this.source = text;
	this.type = type;
};

exports["video/ogg"] = VideoParser;
exports["video/webm"] = VideoParser;
exports["video/mp4"] = VideoParser;
exports["video/quicktime"] = VideoParser;

})();

The key here is adding autoplay: {type: "string", value: ""}, and loop: {type: "string", value: ""}, inside the attributes: list, and removing the default controls: {type: "string", value: "controls"},. Adapt to your own personal requirements.

Disadvantages

  • Modifying core system tiddlers
  • Changes are global, all video tiddlers will behave as defined here

Advantages

  • No copying of huge base64 strings
  • Can still download binary data regularly

:warning:Note: For this to work you have to save your wiki and reload.

You mean using filter expression to get base64 of another video tiddler?

If this works, maybe we can create a [video[xxxtiddler]] syntax in the core as a shortcut for it.

Binary tiddlers like videos already have their text field stored in base64 format, so all that is required is to concatenate the string data:video/mp4;base64, with the base64 data.

If you could get that info I suspect it’d basically work, but from my testing, transclusion always includes the whole <video tag along with the data, even if transcluding just the text field of such tiddler.

As in using {{My Video Tiddler.mp4!!text}} always yields the whole <video autoplay loop src="data:video/mp4;base64," style="width: 100%; object-fit: contain"></video>

I couldn’t get to the raw base64 data alone, my suspicion is that the video parsing rules automatically add the video tags when you import a video and it gets all stored statically in the text field, rather that added dynamically.

But then again it may just be my ineptitude getting in the way. :sweat_smile:

Try something like this:

<video autoplay loop src=`data:video/mp4;base64,${ [{MyVideoTiddler.mp4}] }$` style="width: 100%; object-fit: contain"></video>
2 Likes

Ah of course, such elegance!
Willem Dafoe Head

A single line of code from the man himself and it solved my issue in a second. No way in hell I’d have figured that out myself.

Thanks Jeremy, works like a charm, just in time to integrate it into my new TiddlyWiki!

Thanks @duarte.framos, and of course no problem: none of this stuff is obvious or self explanatory so you are doing the community a service by raising your questions so that everyone can see (and improve) the answers.

3 Likes

Apologies in advance for the question, but…

<video autoplay loop src=`data:video/mp4;base64,${ [{MyVideoTiddler.mp4}] }$` 
style="width: 100%; object-fit: contain"></video>

In the example above, what is the content of the tiddler {MyVideoTiddler.mp4}?

I can create a tiddler with the title: MyVideoTiddler.mp4
and the contents are the text to an external file on my local drive: 2018-12-28_promo_720.mp4

Result is blank space in a rendered tiddler.

I have created a tiddler that plays video (but no audio) using src=`foo` :

<video autoplay loop controls
src=`file:///Users/jwh/Library/CloudStorage/Dropbox/Movies/2018-12-28_promo_720.mp4`
style="width: 100%; object-fit: contain"></video>

How do I get audio in a MP4 file rendered?

It is the tiddler resulting from importing an MP4 file into TiddlyWiki.

You can also create a tiddler of the type video/mp4 and set a _canonical_uri field to point to the file location of the video file.

I have learned that mp4 files will play with audio if the single file TW5 wiki is accessed directly from Dropbox using Firefox browser.

There is no audio when the single file wiki is accessed (from Dropbox) using TiddlyDesktop.

Since TiddlyDesktop is my preferred workflow, does anyone know a quick fix?

A user in another thread explained the issue with MP4 audio in TiddlyDesktop, which apparently amounts to a royalty issue with “headless chrome”. His solution was to use WEBM instead, but I’d also be interested in a solution for MP4.

1 Like