Loading repository data…
Loading repository data…
faneca / repository
A pure-javascript, no plug-ins needed (hence portable to several -ideally all- [Anki](https://apps.ankiweb.net/) clients) implementation of a feature-full, HTML embedded in-card media player together with a multable card template allowing the random selection of one of its variants while reviewing
A pure-javascript implementation -- needing no plugins, hence portable to several (ideally all) Anki clients -- of a feature-full HTML embedded-in-card media player, together with a multable card template allowing the random selection of one of its variants while reviewing.
This is a proof-of-concept deck you're supposed to use as a basis to build your own. I provide the deck in several formats.
First and foremost, as an anki2 file, the native format used by Anki.
The file should include everything that's needed to start adapting it
to your needs.
The deck is also available as a shared deck in Anki's cloud here.
Apart from that, I provide all the files I've used to build the deck.
Inside the collections.media folder is the heart of this idea:
_random-media.js and _random-media.css. These two should be included in
the template of your cards, together with a few more things. Your notes should
also hold some bookmarking information for this to work.
Another file you'll probably want to check if you intend to include your own
videos, as you should, is the conversion script webm-convert.sh, as the
formats you can include are more limited than usual.
Please take into account this is in alpha status yet. Expect some rough edges, specially when editing your card templates. I've included a small section on that at the end.
The deck was tested with Anki Desktop 2.0 on Linux, with Ankidroid 2.8 and with recent versions of Firefox and Chromium running Ankiweb on a tab.
There are two main selling points for this deck (apart from being free ;-).
The first selling point is the inclusion of an embedded HTML player inside your cards.
Anki already does a decent job when dealing with media files. But when we want to get fancy, we find ourselves too limited by it. To implement the features I wanted, embedding an HTML + javascript-powered player was the best and most portable approach:
We can see how it's possible to:
The other strong point of this deck is the randomization of context when testing your memory against a single fact, to decouple the thing you really try to memorize from the circumstances surrounding it.
The idea is not really new. There are lots of different variations on this same idea out there:
But the thing is, here it's applied successfully to media files as well, so the possibilities of the HTML player can give a really nice experience.
With both features, it's possible to implement cards in the same fashion as those from, say, Delvinlanguage.
This randomization feature is more or less decoupled, in the sense that you could use the exact same javascript and css files without the need to really include media files, to construct a text-only deck with randomization, for instance.
Inspired by services like Delvinlanguage, Mainingu or Supernative, I wanted to implement the same kind of functionality on the SRS flashcard ecosystem of Anki. In order to be on pair, feature wise, with those services there are a series of obstacles we need to solve.
For starters, Anki clients, like the desktop one or Ankidroid, resort to external, platform-dependent players to relay them the task of playing media files, even though cards in Anki clients are rendered on an embedded webviewer component that, potentially, can handle them. Actually, relying on dedicated media players is not a bad choice: a lot more media formats can be reliably included in decks that with your run-of-the-mill webviewer; and for a vast category of audio-based cards it makes more sense to keep working that way.
But if we want to give the users some goodies, like a fast UI to modify the speed at which the reproduction should run or asking it to loop indefinitely, or even to be able to jump to the "backside" of the card without cutting the audio or video that was playing, we need more tools than what Anki provides.
As we aim for feature parity, another difficulty lies it the way the SRS
systems of Delvinlanguage and company work: on of the things offered is a
unified way to treat a sole fact (the thing we want to test our memory
against, for the most efficient use of SRS systems it's better if there's only
one of these facts on each card) as a unit, scheduling it as such, and
yet render the card on a random way to avoid potentially harmful associations
of the fact with the context of the card. Delvinlanguage, for instance, tests
each word with one randomly chosen video (which includes the word) from their
database, on a cloze-delete
fashion.
That way, you don't have several cards for the same word, avoiding the undesirable effect of them interfering with each other's schedules but, at the same time, you've got yourself dynamical card context.
A final consideration is that all of this could most likely be implemented as a extension (or plug-in, or add-on, I'm not sure the terminology is homogeneous across all clients), for instance with python for the desktop, with Android companion applications for Ankidroid, and so on. But it'd be a nightmare to build and maintain if we want to support all platforms, and some of them (e.g. Ankiweb) don't support extensions at all... at least if we don't stretch too much the meaning, since a browser running an instance of Ankiweb supports javascript or general-purpose browser extensions.
The first thing we should take into account is the audio and video formats
to which we are limited if we want to support a big portion of the Anki
clients. For that, after some tests, for video files I've chosen the
webm format with codecs VP9 for
the video streams and Opus for the audio streams; for audio-only media I'm
currently going with the ogg /
vorbis combo, but mp3 should be
safe too (with the added bonus of being previewable in the cloud's portfolio
of shared decks, which ogg is not, at present).
There's just one little gotcha, though: webm is not among the formats
"natively" recognized by Anki 2.0, so adding those files to your decks through
the GUI requires knowing how to workaround this. It's really no big deal
and I hope it gets corrected imminently when Anki 2.1 gets out -it's in RC2
as of this writing-. If you're deck is private, so you know beforehand which
devices are going to be used, you could resort to other formats like mp4.
Another consideration is that we need to define some artifacts in our
notes and templates to make them work correctly with this software.
For instance, we'll keep fields containing references to the media files in
the usual Ankian way; but at the same time, due to some idiosyncrasies in
the way Anki treats this kind of fields, we'll need to include in sister
fields the exact same name of the file, but naked: i.e. if a normal
media field contains [audio:hello.ogg], we'll have to have an adjacent
field whose content will be simply hello.ogg.
Actually, we aren't going to use the normal media fields anywhere in our templates: the reason we need them in the card is just so we can make Anki still understand those files are being used by the cards, because the naked ones aren't the hint it's looking for, so they won't get correctly processed when synchronizing or checking the collection if we leave them out.
I've included the script web-convert.sh as an example of how to make the
conversion of files. It uses ffmpeg
with libvpx and
libopus. Explaining
how to install them all is outside the scope of this guide, but most Linux
distributions include them already installed or give easy means to do it;
brew for MacOS X should be on par, and I don't think it'd really that hard
on Windows.
Ideally you should read that bash script and adapt it to your needs. For
example, adding audio to the resulting files is explained in commens there.
For audio, mp3 or ogg are pervasive formats which lots of programs can
produce and they should work out of the box for most clients.
As explained before, we'll need some extra fields to get this working.
Let's see one of our cards:
I recommend always having a sort of card_id, unique for each card, preferably
numerical and sequential. But it's not really required for this software to
work.
Unless all your notes have the same number of "variants" or "options", we'll
need a field holding this number for each note (otherwise we could put the
constant number directly on the template). Here it is named options.
Then you'll have a number of fields that would be the same as with any regular
type of note... But some of them will come in groups of size options. In
general, on a single card, you'll probably want only fields without group
(the loners) and fields coming in options packages.
The task of the javascript is to choose one number from 1 to options and
for each group of fields show only the one corresponding to that field.
The numbers or names of the fields are not really important here. The real
place where the groups are set in stone is in the HTML template. But it's
highly recommended to keep a congruent naming system for the groups.
Let's see the example templates included with the note type Random Media
in the deck, and then we'll start explaining them from bottom to top.
Front:
<!-- --><script src="_random-media.js" random-media-count="{{options}}"></script><!-- -->
<link rel="stylesheet" type="text/css" h