npm package: @fysikrevy/av-main
Description: A js-script and css files for running fysikrevyens AV in one or more browsers.
Author: Kristoffer Levin Hansen
Latest version: 1.4.2
Deprecated: false

Det her er scriptet, der kører browser-delen af fysikrevyen™s
AV-system, og de tilhørende css-filer.

Selve præsentationen kan køre indlæst i en browser fra filsystemet,
men de mere avancerede funktioner (fjernstyringssiden, synkronisering
mellem flere sider, oversættelse af undertekstformater) kræver at de
bliver hentet via serverdelen
[sse-server](https://www.npmjs.com/package/@fysikrevy/sse-server).

# Hurtig start, på punktform

(0) Hent og installer [node.js](https://nodejs.org/). I tilfælde af
  tvivl, gå efter LTS versionen.
  
1. Lav en ny mappe til revyen, og naviger til den i en terminal.

2. Installer server-delen globalt.

        ] npm install -g @fysikrevy/sse-server

3. Start en ny `npm`-pakke, som kan holde styr på vores afhængigheder:

        ] npm init

   `npm` vil nu spørge efter en masse informationer. Siden det ikke er
   meningen, at denne pakke skal udgives i `npm` er det sikkert bare
   at skippe disse spørgsmål, ved at trykke enter ved hver.

4. Hent denne pakke.

        ] npm install @fysikrevy/av-main

5. Kopier filen `node_modules/@fysikrevy/av-main/revy-template.html` i
   din revymappe (kald den fx `revy.html`), og skriv dine overtekster
   dér.
   
    For automatisk omskrivning af .tex-filer til html, kig i
    [av-helpers](https://www.npmjs.com/package/@fysikrevy/av-helpers). Der
    er eksempler på hvad der kan stå i et revy-html-dokument i
    [av-demo](https://www.npmjs.com/package/@fysikrevy/av-demo). 
    
6. Start serveren, ved at skrive 

        ] sse-server
        
    Naviger et browser-vindue på projektoren til
    
        localhost/revy.html
        
    og et andet browser-vindue på din egen skærm til
    
        localhost/revy.remote
        
    Forhåbentlig giver fjernstyringssiden sig selv.
    
    Brug Chrome. Firefox ser ud til at have et problem med, hvordan vi
    stopper og starter videoer, og sætter sig fast.
    
    Læg mærke til, at Chrome (og Firefox)
    [blokerer videoer, der prøver at starte sig selv som standard][autoplay].
    Det kan fikses ved at starte chrome med parameteren
    `--autoplay-policy=no-user-gesture-required`. På Windows,
    højreklik på en genvej til Chrome, og sæt parameteren ind helt til
    sidst, efter et mellemrum, i feltet "Destination" (eller
    "Target").

[autoplay]: https://developer.chrome.com/blog/autoplay/

    
Hvad der skal stå i html-filen
==============================

`revy-template.html` giver skelettet af hvad scriptet forventer, at
der står i html-filen. Hvert `article`-element i `section`-elementet
bliver set som overteksterne til en sketch eller sang. Hvis
`article`-elementet har en `id`-attribut, bruger fjernstyringssiden
det som overskrift i oversigten.

Sangtekster
-----------

Sangtekster kommer til at være hovedparten af AV til en
revy. `article`-elementet der inheholder teksten til en sang bør have
klasserne `build` og `lyr`, og hver linje bør være i sit eget
`p`-element. For eksempel:

    <article class="build lyr">
      <p>Bamse og Kylling siger</p>
      <p>SPRÆNG!</p>
    </article>

Det kan være nødvendigt at have flere linjer synlige på samme tid,
eller bryde lange linjer om:

      <p>Det var i nitten-niogfyrre, <br /> eller circa deromkring</p>
    
For ikke at spolere en punchline kan vi skjule en del af en linje
indtil det rigtige øjeblik:

      <p class="build">Det er jo <span>Datalogen!</span></p>
      
Billeder
--------

`img`-elmentet kan bruges hvor som helst. Det kan være brugbart, hvis
et billede har sit eget `div`-element at bo i, så klassen `pagediv`
fylder sin forælder, og centrerer sit indhold. Et dias, som viser en
serie billeder i fuld skærm et ad gangen kan se ud som følger:

    <article class="build kill">
      <div class="pagediv"><img src="billeder/b1.jpg" height="100%"></div>
      <div class="pagediv"><img src="billeder/b2.jpg" height="100%"></div>
      <div class="pagediv"><img src="billeder/b3.jpg" height="100%"></div>
    </article>
    
Videoer
-------

Et dias med en video kan se ud som følger:

    <article class="build" id="bandintro" >
        <video preload="none" >
            <source src="fisk/Poisson.mp4" type="video/mp4" />
            <track src="fisk/Poisson.vtt" 
               kind="subtitles" 
	           srclang="da-DK" default />
        </video>
    </article>

Forudindlæsning er slået fra, ved at sætte `preload` til
`none`, for at forbedre genindlæsningstiden.

Det er for tiden videofiler i mp4 (h.264) format, der har den bedste
chance for at være kompatibel med en given browser. Nogen specifikke
browsere har bredere kompatibilitet, men skal under alle
omstændigheder helst have at vide hvilken type videofil de får, via
`type`-parameteren. Hvis dine fiskekreatørere giver dig videoer i
ubrugelige formater, så er der altid
[handbrake](https://handbrake.fr/).

Vtt-formatet bruges til undertekster i browsere og *ingen andre
steder*<sup>[Citation needed]</sup>. Derfor kan server-delen
konvertere .srt og .ass filer til vtt on-the-fly, så længe de har det
samme navn, op til filtypenavnet.

[backstage-ticker][]
--------------------

Som bliver forklaret på [backstage-ticker][]s egen side, så bliver
tickeren opdateret ved at sende en besked til serveren med en
tekststreng, som indeholder de informationer, som skal vises på
tickeren.

Her i AV™ sætter vi dem ind i diasstakken ved at føje dem til
data-atributten på det element, som bliver aktivt, når
backstage-tickeren skal skifte. I de fleste tilfælde vil det nok være
`<article>`-elementet, som beskriver nummeret, som går på scenen.

Tekststrengen kan kobles til et element, enten direkte på atributten
`data-ticker-info`, så fx:

    <article class="build" id="introsang" 
             data-ticker-info="Introsangen;3:10;actors;Jophiel;ninjas;Høje Sofie"
     ><p>...</p></article>

...eller indirekte, via atributten `data-ticker-ref`, som sættes til
det tilsvarende indeks i et javascript objekt, som hedder
`ticker`. Altså, fx kan strengene holdes samlet i en script-blok i
`<head>`:

    <script>
      let ticker = [ "Publikum;?:??",
                     "Introsangen;3:10;actors;Jophiel;ninjas;Høje Sofie"
                    ]
    </script>

og på selve elementet sættes

    <article class="build" id="introsang" data-ticker-ref="1">
      <p>...</p>
    </article>

således, at når `data-ticker-ref`s værdi tages som et indeks ind i
`ticker`, altså i det her tilfælde `ticker["1"]`, evalueres til den
streng, som skal sendes til backstage-ticker.

En ticker-udløser kan også sættes på underelementer til
`<article>`-elementer, hvis det giver mening. Altså fx:

    <article class="build lyr" id="publikumnonsens" >
      <p>Se championskyer, der tårner sig op</p>
      <p>Se huder der sortner som blæk</p>
      <p data-ticker-ref="0"> Og strålingen smelter din lede krop</p>
      <p> (etc) </p>
    </article>



[backstage-ticker]: https://www.npmjs.com/package/@fysikrevy/backstage-ticker


Justér til skærmen
==================

Helt kort, bliver det styret af css-egenskaberne `margin-left`,
`margin-right` og `transform` for reglerne `.slides > article` og
`.slides > .vidframe`.

De findes i filen `node_modules/@fysikrevy/av-main/av.css`, som er
temmelig lang. Men et sted derinde står der noget i retningen af

    .slides > article {
      
      [...]
      
        margin-left: -960px;
        margin-top: -540px;
         
        transform: scale(1);
      
      [...]
    }

Tallet efter `margin-left` styrer den horisontale position,
`margin-top` styrer den vertikale position og tallet inde i `scale( )`
styrer zoom.

Det er muligt at eksperimentere med de her tal interaktivt i
browserens inspector-vindue (prøv at trykke F12). `av.css` kan
kopieres til revy-mappen, og serveren vil tage den kopi i stedet for
filen i `av-main`-mappen, hvis du vil holde ændringer fri af selve
`av-main`-mappen.

Det der, med flere projektorere
===============================

Ud over `.remote` og `.html` giver serveren seperate versioner af
revy-filen med endelserne `.left`, `.mid` og `.right`. På de sider
vises elementer, som er markeret med en `for` attribut, som enten
matcher sidens endelse, eller `span`, som vises på alle tre sider.

TODO: Lige nu er kun `span` implementeret.

For eksempel, betragt følgende html-brudstykke:

    <article class="lyr kill" id ="23_UskyldigSang">
      <article class="build kill vidframe" for="span">
        <video for="span" preload="none" class="build" dur="0">
          <source src="uskyldig/Empty.m4v" type="video/mp4" class="auto" for="span" />
          <p>Jeg sidder her på kanten af min stol</p>
          <p>Regner på MekRel</p>
          <p>Åh så mange ting jeg ik forstår</p>
          <p>Bare du ku’ fortælle</p>
          <p>Jeg ved jo godt det kun er noget</p>
          <p>Der foregår i mit eget hoved</p>
        </video>
        <video loop for="span" preload="none" class="build">
          <source src="uskyldig/Newton.m4v" type="video/mp4" class="auto"  for="span" />
          <p class="auto">Jeg syn’s jo bare du var sød</p> <!-- newton -->
          <p class="build">Newton vil <span>du</span> <span>læg’ dig</span> </p>
          <p class="build">Ned så jeg ka <span>flæk’ dig</span></p>
          <p>Du ku’ være min stjernefyr</p>
        </video>
      </article>
    </article>
      
Vi forsøger, at bygge to forskellige html-dokumentstrukturer, som kan
vises på to projektorere, men hvor de to dokumenter er enuge om,
hvordan listen over elementer, som skal bygges, ser ud. Altså, som
tidligere nævnt, hvilke elementer, som er præcis ét element under et
element med klassen `build`. Derfor vil hovedprojektoren---den, hvor
siden har endelsen `.html`---ikke vise elementer, som er markeret med
en `for` attribut til en af de andre sider, mens fx siden med endelsen
`.left` *kun* viser elementer, som er markeret `for` `left` eller
`span`.

Så, `.html`-siden vil se ud som om dokumentet kun indeholdt:

    <article class="lyr kill" id ="23_UskyldigSang">
       <p>Jeg sidder her på kanten af min stol</p>
       <p>Regner på MekRel</p>
       <p>Åh så mange ting jeg ik forstår</p>
       <p>Bare du ku’ fortælle</p>
       <p>Jeg ved jo godt det kun er noget</p>
       <p>Der foregår i mit eget hoved</p>
       <p class="auto">Jeg syn’s jo bare du var sød</p> <!-- newton -->
       <p class="build">Newton vil <span>du</span> <span>læg’ dig</span> </p>
       <p class="build">Ned så jeg ka <span>flæk’ dig</span></p>
       <p>Du ku’ være min stjernefyr</p>
    </article>

og fx `.left`-siden vil se ud som om dokumentet kun indeholdt:

    <article class="lyr kill" id ="23_UskyldigSang">
      <video for="span" preload="none" class="build" dur="0">
        <source src="uskyldig/Empty.m4v" type="video/mp4" class="auto" for="span" />
      </video>
      <video loop for="span" preload="none" class="build">
        <source src="uskyldig/Newton.m4v" type="video/mp4" class="auto"  for="span" />
      </video>
    </article>

Men begge sider vil være enige om, at listen over elementer, som skal
bygges er:

1. `<video for="span" preload="none" class="build" dur="0">`
2. `<p>Jeg sidder her på kanten af min stol</p>`
3. `<p>Regner på MekRel</p>`
4. `<p>Åh så mange ting jeg ik forstår</p>`
5. `<p>Bare du ku’ fortælle</p>`
6. `<p>Jeg ved jo godt det kun er noget</p>`
7. `<p>Der foregår i mit eget hoved</p>`
8. `<video loop for="span" preload="none" class="build">`
9. `<p class="build">Newton vil`
10. `<span>du</span>` 
11. `<span>læg’ dig</span>`
12. `<p class="build">Ned så jeg ka`
13. `<span>flæk’ dig</span>`
14. `<p>Du ku’ være min stjernefyr</p>`

(Vi springer elementer med klassen `auto` over, fordi de bliver bygget
automatisk.)

Placeringen af elementerne i billedet styres af reglerne for

    body.right section.slides article[for="span"]{
    
og

    body.left section.slides article[for="span"]{
    
i `av.css`. Det ser ud til, at noget af implementeringen for
`for`-attributter, som ikke er `span` mangler...

Versioner
---------

###### 1.4.2 ######
> Bugfix for lille bigSlide

###### 1.4.1 ######
> Genintroducer README'en

###### 1.4.0 ######
> Indfører koblingen til backstage-ticker.
>
> Også: endnu et forsøg på at fikse størrelsen på de nederste
> elementer i remote-visningen.

###### 1.3.4 ######
> Gør behandling af `rununder` mere konsekvent.

###### 1.3.3 ######
> Antag som udgangspunkt 1080p størrelse for et `article` element, og
> fjern de forskellige `scale`'r for `vidframes`. Det burde også gøre
> `vidframe` overflødig. Automatisk skalering af `article` elementer i
> remote-en. Hvis de ikke har den rigtige størrelse, så søg efter
> "scalesheet" i `AV-script.js`. Så finder du nok den rigtige kode.

###### 1.3.2 ######
> Opdateret "nej"--mekanisme. Den endte med mest at bo i
> server-delen. Et par løste bugs omkring medie-afspilning. Udvidet
> README.

###### 1.2.0
> Opdateret mediekontrol, så "goto" (når man navigerer ved at klikke
> på et element, i modsætning til frem/tilage taster) starter medier
> forfra.

###### 1.1.1 - 1.1.3

> Fixet interaktionen mellem `prev`, `last-built` og `auto` (det burde
> fungere bedre, at gå baglæns i en slide). Introduceret jquery som
> afhængighed, for et nemmere liv. Introduceret `.build-me` som
> alternativ til `.build > *`.

##### 1.1.0 #####
> Fix: Kan lave mellemrum i d-linjer igen. 
> Ny implementering af mimic-mekanisme. Kan nu afspille
> videoer. Muligvis begrænset bagud-kompatabilitet.