Makes IPFS video chain
This commit is contained in:
parent
aa99769de5
commit
5da57550d2
29
README.md
29
README.md
|
@ -1,6 +1,29 @@
|
|||
# bunkerbox
|
||||
|
||||
Chaine video IPFS.
|
||||
Source: https://crowdbunker.com
|
||||
PUBLICATION : https://tube.copylaradio.com/ipns/k51qzi5uqu5djt17zonkpg1cb8hrxhahpesybusz8q57j4ocqm0qlc6s99z60x
|
||||
Sauvegarde de Chaine video dans IPFS / IPNS.
|
||||
- Source : https://crowdbunker.com
|
||||
|
||||
En suivant le même principe, on peut facilement créer des chaines de vidéos depuis d'autres sources (webcam, etc...)
|
||||
|
||||
```
|
||||
# INSTALL
|
||||
mkdir ~/workspace && cd ~/workspace
|
||||
git clone https://git.p2p.legal/qo-op/bunkerbox.git
|
||||
|
||||
# RUN
|
||||
cd ~/workspace/bunkerbox
|
||||
./crowdbunker.sh
|
||||
```
|
||||
|
||||
# Explications
|
||||
|
||||
crowdbunker.sh est une boucle qui inscrit les denrières vidéos dans une liste publiée au travers d'une chaine de vidéos.
|
||||
- PUBLICATION qo-op DEV : https://tube.copylaradio.com/ipns/k51qzi5uqu5djt17zonkpg1cb8hrxhahpesybusz8q57j4ocqm0qlc6s99z60x
|
||||
|
||||
1. Récupère la liste des 30 dernières video publiées sur https://crowdbunker.com
|
||||
2. Télécharge les fichiers video et audio (360p de préférence) et leurs fichiers m3u8
|
||||
3. Ajoute le lecteur videojs dans index.html et met à jour history.json
|
||||
4. Publie localement ou sur la clef IPFS qo-op ou au travers du TestNet astrXbian
|
||||
|
||||
Pour revenir en mode "debug", effacez le fichier ~/.zen/bunkerbox/choice
|
||||
|
||||
|
|
|
@ -0,0 +1,244 @@
|
|||
#!/bin/bash
|
||||
################################################################################
|
||||
# Author: Fred (support@qo-op.com)
|
||||
# Version: 0.1
|
||||
# License: AGPL-3.0 (https://choosealicense.com/licenses/agpl-3.0/)
|
||||
################################################################################
|
||||
mkdir -p ~/.zen/bunkerbox # BunkerBOX temp directory
|
||||
# Fred MadeInZion, [20/03/2022 23:03]
|
||||
# Script qui capture et transfert dans IPFS le flux des nouvelles vidéos de https://crowdbunker.com/
|
||||
# le resultat est inscrit dans une chaine video accessible localement ou publiée au travers de qo-op
|
||||
# ou du TestNET astrXbian, videoclub entre amis d'amis...
|
||||
|
||||
MY_PATH="`dirname \"$0\"`" # relative
|
||||
MY_PATH="`( cd \"$MY_PATH\" && pwd )`" # absolutized and normalized
|
||||
ME="${0##*/}"
|
||||
TS=$(date -u +%s%N | cut -b1-13)
|
||||
|
||||
[[ ! $(which ipfs) ]] && echo "EXIT. Vous devez avoir installé ipfs CLI sur votre ordinateur" && echo "RDV sur https://dist.ipfs.io/#go-ipfs" && exit 1
|
||||
|
||||
YOU=$(ps auxf --sort=+utime | grep -w ipfs | grep -v -E 'color=auto|grep' | tail -n 1 | cut -d " " -f 1) || echo " warning ipfs daemon not running"
|
||||
isLAN=$(hostname -I | awk '{print $1}' | head -n 1 | cut -f3 -d '/' | grep -E "(^127\.)|(^192\.168\.)|(^fd42\:)|(^10\.)|(^172\.1[6-9]\.)|(^172\.2[0-9]\.)|(^172\.3[0-1]\.)|(^::1$)|(^[fF][cCdD])/")
|
||||
|
||||
IPFSNGW="https://tube.copylaradio.com"
|
||||
IPFSNGW="http://127.0.0.1:8080"
|
||||
|
||||
[[ ! $isLAN ]] && IPFSNGW="https://$(hostname)"
|
||||
echo "IPFS GATEWAY $IPFSNGW"
|
||||
|
||||
## GET LATEST VIDEOS
|
||||
VWALLURL="https://api.crowdbunker.com/post/all"
|
||||
curl -s $VWALLURL -H "Accept: application/json" > ~/.zen/bunkerbox/crowd.json
|
||||
|
||||
## LOOP THROUGH
|
||||
for VUID in $(cat ~/.zen/bunkerbox/crowd.json | jq -r '.posts | .[] | .video.id'); do
|
||||
[[ "$VUID" == "null" ]] && echo "MESSAGE... Bypassing..." && echo && continue
|
||||
echo "Bunker BOX : Adding $VUID"
|
||||
mkdir -p ~/.zen/bunkerbox/$VUID/media
|
||||
|
||||
URL="https://api.crowdbunker.com/post/$VUID/details"
|
||||
# echo "WISHING TO EXPLORE $URL ?"; read TEST; [[ "$TEST" != "" ]] && echo && continue
|
||||
curl -s $URL -H "Accept: application/json" -o ~/.zen/bunkerbox/$VUID/$VUID.json
|
||||
|
||||
# STREAMING LIVE ?
|
||||
echo ">>> Extracting video caracteristics from ~/.zen/bunkerbox/$VUID/$VUID.json"
|
||||
ISLIVE=$(cat ~/.zen/bunkerbox/$VUID/$VUID.json | jq -r .video.isLiveType)&& [[ "$ISLIVE" == "true" ]] && echo "LIVE... "
|
||||
LIVE=$(cat ~/.zen/bunkerbox/$VUID/$VUID.json | jq -r .video.isLiveActive) && [[ "$LIVE" == "true" ]] && echo "STREAMING... Bypassing..." && echo && continue
|
||||
DURATION=$(cat ~/.zen/bunkerbox/$VUID/$VUID.json | jq -r .video.duration) && [[ $DURATION == 0 ]] && echo "NOT STARTED YET" && echo && continue
|
||||
TITLE=$(cat ~/.zen/bunkerbox/$VUID/$VUID.json | jq -r .video.title | sed "s/'/ /g" | sed 's/"/ /g') # Remove quote
|
||||
CHANNEL=$(cat ~/.zen/bunkerbox/$VUID/$VUID.json | jq -r .channel.name)
|
||||
ORGUID=$(cat ~/.zen/bunkerbox/$VUID/$VUID.json | jq -r .organization.uid)
|
||||
ORGNAME=$(cat ~/.zen/bunkerbox/$VUID/$VUID.json | jq -r .organization.name)
|
||||
ORGBANNER=$(cat ~/.zen/bunkerbox/$VUID/$VUID.json | jq -r .organization.banner.url)
|
||||
|
||||
HLS=$(cat ~/.zen/bunkerbox/$VUID/$VUID.json | jq -r .video.hlsManifest.url)
|
||||
MEDIASOURCE=$(echo $HLS | rev | cut -d '/' -f 2- | rev)
|
||||
echo "$TITLE ($DURATION s)"
|
||||
|
||||
## CHECK PUBLISH MODE
|
||||
[[ ! -f ~/.zen/bunkerbox/choice ]] && echo "READY TO PROCESS ? ENTER. Any character sent means next." && read TEST && [[ "$TEST" != "" ]] && echo && continue ## NO CHOICE MADE
|
||||
start=`date +%s`
|
||||
echo "$HLS"
|
||||
curl -s $HLS -o ~/.zen/bunkerbox/$VUID/$VUID.m3u8
|
||||
# cat ~/.zen/bunkerbox/$VUID/$VUID.m3u8
|
||||
|
||||
echo ">>>>>>>>>>>>>>>> Downloading VIDEO"
|
||||
# Choose 360p or 480p or 240p
|
||||
VSIZE=360 && VIDEOHEAD=$(cat ~/.zen/bunkerbox/$VUID/$VUID.m3u8 | grep -B1 ${VSIZE}p | head -n 1) && VIDEOSRC=$(cat ~/.zen/bunkerbox/$VUID/$VUID.m3u8 | grep ${VSIZE}p | tail -n 1 | cut -f 1 -d '.')
|
||||
[[ "$VIDEOSRC" == "" ]] && VSIZE=480 && VIDEOHEAD=$(cat ~/.zen/bunkerbox/$VUID/$VUID.m3u8 | grep -B1 ${VSIZE}p | head -n 1) && VIDEOSRC=$(cat ~/.zen/bunkerbox/$VUID/$VUID.m3u8 | grep ${VSIZE}p | tail -n 1 | cut -f 1 -d '.')
|
||||
[[ "$VIDEOSRC" == "" ]] && VSIZE=240 &&VIDEOHEAD=$(cat ~/.zen/bunkerbox/$VUID/$VUID.m3u8 | grep -B1 ${VSIZE}p | head -n 1) && VIDEOSRC=$(cat ~/.zen/bunkerbox/$VUID/$VUID.m3u8 | grep ${VSIZE}p | tail -n 1 | cut -f 1 -d '.')
|
||||
VTHUMB="$(cat ~/.zen/bunkerbox/$VUID/$VUID.json | jq -r --arg VSIZE "$VSIZE" '.video.thumbnails[] | select(.height == $VSIZE) | .url')"
|
||||
|
||||
echo ">>>>>>>>>>>>>>>> Downloading Video $VSIZE Thumbnail"
|
||||
curl -s $VTHUMB -o ~/.zen/bunkerbox/$VUID/media/$VUID.jpg
|
||||
[[ ! -f ~/.zen/bunkerbox/$VUID/media/$VUID.jpg ]] && cp ${MY_PATH}/images/astroport.jpg ~/.zen/bunkerbox/$VUID/media/$VUID.jpg # CORRECT MISSING THUMB
|
||||
|
||||
echo "VIDEOSRC=$MEDIASOURCE/$VIDEOSRC"
|
||||
# Downloading Video m3u8 and Video
|
||||
[[ ! -f ~/.zen/bunkerbox/$VUID/media/$VIDEOSRC.m3u8 ]] && curl -s $MEDIASOURCE/$VIDEOSRC.m3u8 -o ~/.zen/bunkerbox/$VUID/media/$VIDEOSRC.m3u8
|
||||
[[ ! -f ~/.zen/bunkerbox/$VUID/media/$VIDEOSRC ]] && curl $MEDIASOURCE/$VIDEOSRC -o ~/.zen/bunkerbox/$VUID/media/$VIDEOSRC
|
||||
|
||||
echo ">>>>>>>>>>>>>>>> Downloading AUDIO"
|
||||
AUDIOLINE=$(cat ~/.zen/bunkerbox/$VUID/$VUID.m3u8 | grep '=AUDIO')
|
||||
AUDIOFILE=$(echo $AUDIOLINE | rev | cut -d '.' -f 2- | cut -d '"' -f 1 | rev)
|
||||
echo "AUDIO=$MEDIASOURCE/$AUDIOFILE"
|
||||
# Downloading Audio m3u8 and Audio
|
||||
[[ ! -f ~/.zen/bunkerbox/$VUID/media/$AUDIOFILE.m3u8 ]] && curl -s $MEDIASOURCE/$AUDIOFILE.m3u8 -o ~/.zen/bunkerbox/$VUID/media/$AUDIOFILE.m3u8
|
||||
[[ ! -f ~/.zen/bunkerbox/$VUID/media/$AUDIOFILE ]] && curl $MEDIASOURCE/$AUDIOFILE -o ~/.zen/bunkerbox/$VUID/media/$AUDIOFILE
|
||||
|
||||
echo ">>>>>>>>>>>>>>>> CREATING $VSIZE M3U8"
|
||||
echo "#EXTM3U
|
||||
#EXT-X-VERSION:6
|
||||
#EXT-X-INDEPENDENT-SEGMENTS
|
||||
|
||||
$AUDIOLINE
|
||||
|
||||
$VIDEOHEAD
|
||||
$VIDEOSRC.m3u8
|
||||
|
||||
" > ~/.zen/bunkerbox/$VUID/media/$VUID.m3u8
|
||||
ls ~/.zen/bunkerbox/$VUID/media/
|
||||
##########################################################################
|
||||
echo "##########################################################################"
|
||||
echo ">>>>>>>>>>>>>>>> ADDING index.html"
|
||||
# COPY index, style, js AND data
|
||||
cp -R ${MY_PATH}/templates/styles ~/.zen/bunkerbox/$VUID/media/
|
||||
cp -R ${MY_PATH}/templates/js ~/.zen/bunkerbox/$VUID/media/
|
||||
cp ${MY_PATH}/templates/videojs.html ~/.zen/bunkerbox/$VUID/media/index.html
|
||||
cp ${MY_PATH}/images/astroport.jpg ~/.zen/bunkerbox/$VUID/media/
|
||||
|
||||
# Add current/latest common history reversed
|
||||
if [[ -f ~/.zen/bunkerbox/history.json ]]; then
|
||||
# qo-op get latest history.json
|
||||
[[ "$(cat ~/.zen/bunkerbox/choice)"=="qo-op" ]] && ipfs get -o ~/.zen/bunkerbox/history.qo-op.json /ipns/$(cat ~/.zen/bunkerbox/qo-op)/history.json
|
||||
# FUSION/REPLACEMENT WHAT TODO ?
|
||||
##
|
||||
echo '{
|
||||
"Videos":' > ~/.zen/bunkerbox/$VUID/media/history.json
|
||||
cat ~/.zen/bunkerbox/history.json | jq '.[] | reverse' >> ~/.zen/bunkerbox/$VUID/media/history.json
|
||||
echo '}' >> ~/.zen/bunkerbox/$VUID/media/history.json
|
||||
else
|
||||
## NEW history
|
||||
[[ ! $(cat ~/.zen/bunkerbox/history.json | grep Videos) ]] && cp ${MY_PATH}/templates/data/history.json ~/.zen/bunkerbox/history.json
|
||||
cp ~/.zen/bunkerbox/history.json ~/.zen/bunkerbox/$VUID/media/history.json
|
||||
fi
|
||||
# Using relative links
|
||||
sed "s/_IPFSROOT_/./g" ${MY_PATH}/templates/videojs.html > ~/.zen/bunkerbox/$VUID/media/index.html
|
||||
sed -i "s/_VUID_/$VUID/g" ~/.zen/bunkerbox/$VUID/media/index.html
|
||||
# sed -i s/_DATE_/$(date -u "+%Y-%m-%d#%H:%M:%S")/g ~/.zen/bunkerbox/$VUID/media/index.html # Different Copy Makes Different Chains !
|
||||
sed -i "s~_TITLE_~$TITLE~g" ~/.zen/bunkerbox/$VUID/media/index.html
|
||||
sed -i "s~_CHANNEL_~$CHANNEL~g" ~/.zen/bunkerbox/$VUID/media/index.html
|
||||
|
||||
echo ">>>>> ADDING TO IPFS : ipfs add -rwH ~/.zen/bunkerbox/$VUID/media/* "
|
||||
echo
|
||||
IPFSROOT=$(ipfs add -rwHq ~/.zen/bunkerbox/$VUID/media/* | tail -n 1)
|
||||
INDEX="/ipfs/$IPFSROOT"
|
||||
|
||||
VMAIN="/ipfs/$IPFSROOT/$VUID.m3u8"
|
||||
# UPDATING original JSON
|
||||
cat ~/.zen/bunkerbox/$VUID/$VUID.json | jq ".video.hlsManifest.url = \"$VMAIN\"" > ~/.zen/bunkerbox/$VUID/media/$VUID.json
|
||||
echo "M3U8 : $IPFSNGW$VMAIN"
|
||||
|
||||
## UPDATE GLOCAL HISTORY ?
|
||||
IsThere=$(cat ~/.zen/bunkerbox/history.json | jq .Videos[].link | grep $VUID)
|
||||
if [[ ! $IsThere ]]; then
|
||||
echo "Add $INDEX to ~/.zen/bunkerbox/$VUID/media/history.json"
|
||||
cat ~/.zen/bunkerbox/history.json | jq '.Videos += [{"link": "<a href='"'_INDEX_'"'><img src='"'_INDEX_/_VUID_.jpg'"' height=80 ></a><br>'"'_TITLE_'"'"}]' > ~/.zen/bunkerbox/$VUID/media/history.json
|
||||
echo $INDEX
|
||||
sed -i "s~_INDEX_~$INDEX~g" ~/.zen/bunkerbox/$VUID/media/history.json
|
||||
echo $VUID
|
||||
sed -i "s~_VUID_~$VUID~g" ~/.zen/bunkerbox/$VUID/media/history.json
|
||||
echo $TITLE
|
||||
sed -i "s~_TITLE_~$TITLE~g" ~/.zen/bunkerbox/$VUID/media/history.json
|
||||
# COULD BE DONE LIKE THAT
|
||||
# cat ~/.zen/bunkerbox/$VUID/media/history.json | jq --arg INDEX "$INDEX" --arg TITLE "$TITLE" '.Videos += [{"link": "<a href='''$INDEX''' >'''$TITLE'''</a>"}]' > ~/.zen/bunkerbox/history.json
|
||||
echo "Mise à jour ~/.zen/bunkerbox/history.json"
|
||||
[[ "$(cat ~/.zen/bunkerbox/$VUID/media/history.json)" == "" ]] && echo "FATAL ERROR MAJ" && exit 1
|
||||
[[ -f ~/.zen/bunkerbox/$VUID/media/history.json ]] && cp -f ~/.zen/bunkerbox/$VUID/media/history.json ~/.zen/bunkerbox/history.json
|
||||
fi
|
||||
|
||||
echo "<meta http-equiv=\"refresh\" content=\"0;URL=$INDEX\">" > ~/.zen/bunkerbox/index.html
|
||||
echo "ACTUEL INDEX $IPFSNGW/ipfs/$IPFSROOT"
|
||||
echo "OLD JSON : $IPFSNGW/ipfs/$IPFSROOT/history.json"
|
||||
|
||||
PS3="Comment voulez-vous continuer et publier la collecte ? "
|
||||
choices=("debug" "local" "qo-op" "astrXbian")
|
||||
fav=$(cat ~/.zen/bunkerbox/choice)
|
||||
[[ ! $fav ]] && select fav in "${choices[@]}"; do [[ $fav ]] && break; done
|
||||
case $fav in
|
||||
"local")
|
||||
echo 'local' > ~/.zen/bunkerbox/choice
|
||||
echo "Historique LOCAL = ~/.zen/bunkerbox/history.json"
|
||||
continue
|
||||
;;
|
||||
"astrXbian")
|
||||
[[ ! -d ~/.zen/astrXbian ]] && echo "DEV ZONE - Installez astrXbian SVP ... P2P VideoClub DEMO - DEV ZONE !" && exit 1
|
||||
[[ ! $IPFSNODEID ]] && echo "Missing IPFSNODEID. Exit" && exit 1
|
||||
echo 'astrXbian' > ~/.zen/bunkerbox/choice
|
||||
mkdir -p ~/.zen/ipfs/.$IPFSNODEID/astroport/bunkerbox
|
||||
echo "<meta http-equiv=\"refresh\" content=\"0;URL=$INDEX\">" > ~/.zen/ipfs/.$IPFSNODEID/astroport/bunkerbox/index.html
|
||||
cp ~/.zen/bunkerbox/history.json ~/.zen/ipfs/.$IPFSNODEID/astroport/bunkerbox/
|
||||
echo "BALISE Station $IPFSNGW/ipns/$IPFSNODEID/.$IPFSNODEID/astroport/bunkerbox/ propagation au prochain cycle astrXbian"
|
||||
continue
|
||||
;;
|
||||
"qo-op")
|
||||
if [[ ! $(ipfs key list | grep 'qo-op') ]]; then
|
||||
echo "MIssing qo-op key! Clef qo-op manquante!"
|
||||
echo "get it from your best friend and do not break confidence ring!"
|
||||
echo "récupérez la auprès de votre meilleur ami. Et ne brisez pas la chaine de confiance!"
|
||||
|
||||
echo "Contact support@qo-op.com for help! Envoyez un email pour obtenir assistance."
|
||||
echo "Utiliser la clef de DEV ? ENTRER pour OUI. Répondez qqch pour NON."
|
||||
read KDEV
|
||||
[[ "$KDEV" != "" ]] && echo "BRAVO! Confidence is in the KEY. La confiance est dans la CLEF." && break ## NO CHOICE MADE
|
||||
|
||||
## USE DEV KEY
|
||||
echo "k51qzi5uqu5djt17zonkpg1cb8hrxhahpesybusz8q57j4ocqm0qlc6s99z60x" > ~/.zen/bunkerbox/qo-op
|
||||
cp ${MY_PATH}/key_ofxs233q ~/.ipfs/keystore/
|
||||
|
||||
mkdir -p /tmp/$VUID
|
||||
echo "<meta http-equiv=\"refresh\" content=\"0;URL=$INDEX\">" > /tmp/$VUID/index.html
|
||||
cp ~/.zen/bunkerbox/history.json > /tmp/$VUID/history.json
|
||||
echo "$TS" > /tmp/$VUID/ts # TimeStamping
|
||||
VROOT=$(ipfs add -wHq /tmp/$VUID/* | tail -n 1)
|
||||
ipfs name publish --key=qo-op /ipfs/$VROOT
|
||||
echo "qo-op : $IPFSNGW/ipns/$IPNS/history.json /ipfs/$VROOT"
|
||||
else
|
||||
## WRITE qo-op IPNS key
|
||||
ipfs key list -l | grep 'qo-op' | cut -f 1 -d ' ' > ~/.zen/bunkerbox/qo-op
|
||||
fi
|
||||
echo 'qo-op' > ~/.zen/bunkerbox/choice
|
||||
IPNS=$(cat ~/.zen/bunkerbox/qo-op)
|
||||
echo "Votre chaine vidéo qo-op /ipns/$IPNS"
|
||||
echo
|
||||
|
||||
InHere=$(cat ~/.zen/bunkerbox/history.qo-op.json | jq .Videos[].link | grep $VUID)
|
||||
if [[ ! $InHere ]]; then
|
||||
echo "NOUVELLE VIDEO."
|
||||
mkdir -p /tmp/$VUID
|
||||
echo "<meta http-equiv=\"refresh\" content=\"0;URL=$INDEX\">" > /tmp/$VUID/index.html
|
||||
cp ~/.zen/bunkerbox/history.json /tmp/$VUID/history.json
|
||||
echo "$TS" > /tmp/$VUID/ts # TimeStamping
|
||||
|
||||
VROOT=$(ipfs add -wHq /tmp/$VUID/* | tail -n 1)
|
||||
ipfs name publish --key=qo-op /ipfs/$VROOT
|
||||
echo "qo-op : $IPFSNGW/ipns/$IPNS/"
|
||||
echo "qo-op : $IPFSNGW/ipns/$IPNS/history.json"
|
||||
fi
|
||||
#[[ $VUID != "" ]] && rm -Rf /tmp/$VUID # Cleaning
|
||||
continue
|
||||
;;
|
||||
"debug")
|
||||
echo "debug"
|
||||
> ~/.zen/bunkerbox/choice
|
||||
break
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
##########################################################################
|
||||
# cat ~/.zen/bunkerbox/$VUID/media/$VUID.json | jq -r .video.hlsManifest.url
|
||||
|
||||
end=`date +%s`; echo Duration `expr $end - $start` seconds.
|
||||
|
||||
done
|
Binary file not shown.
After Width: | Height: | Size: 40 KiB |
|
@ -0,0 +1 @@
|
|||
@^‡’@ƒrÈEkã¿ù¬ˆ¢Ügá]Ì)ÄTÙ‹á
1šU…‘a¨ƒŽfGíO+Ÿ~"ÎÇ=ûZI5ê£*¶A
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"Videos": [
|
||||
|
||||
]
|
||||
}
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,192 @@
|
|||
:root {
|
||||
|
||||
--rouge: hsl(0, 98.8%, 33.5%);
|
||||
--rouge-fonce: hsl(0, 75%, 33.5%);
|
||||
|
||||
--noir-complet: black;
|
||||
--noir-fonce: hsl(0, 30%, 2.1%);
|
||||
--noir-moyen: hsl(0, 15%, 3.1%);
|
||||
--noir-clair: hsl(0, 5%, 7.1%);
|
||||
|
||||
--blanc: hsla(0, 0%, 100%, 1);
|
||||
--blanc-fort: hsla(0, 0%, 100%, 0.75);
|
||||
--blanc-semi-transparent: hsla(0, 0%, 100%, 0.25);
|
||||
}
|
||||
|
||||
|
||||
body {
|
||||
|
||||
background: var(--noir-fonce);
|
||||
color: white;
|
||||
font-family: Roboto,sans-serif;
|
||||
}
|
||||
|
||||
header {
|
||||
|
||||
background: var(--noir-clair);
|
||||
}
|
||||
|
||||
|
||||
header * {
|
||||
|
||||
color: var(--rouge);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
header span {
|
||||
|
||||
color: white;
|
||||
}
|
||||
|
||||
#pinFilter ul li a {
|
||||
|
||||
background-color: var(--blanc);
|
||||
}
|
||||
|
||||
#pinFilter ul li.selected a {
|
||||
|
||||
background-color: var(--rouge);
|
||||
}
|
||||
|
||||
|
||||
ul#tagsList,
|
||||
ul#narrowingTags {
|
||||
|
||||
list-style: none;
|
||||
margin-left: 0;
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
ul#tagsList li,
|
||||
ul#narrowingTags li {
|
||||
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
ul#tagsList a,
|
||||
ul#tagsList a:visited {
|
||||
|
||||
text-decoration: none;
|
||||
color: var(--rouge-fonce);
|
||||
}
|
||||
|
||||
#narrowingTags a,
|
||||
#narrowingTags a:visited {
|
||||
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
#narrowingTags li {
|
||||
|
||||
border-radius: 1rem;
|
||||
}
|
||||
|
||||
#narrowingTags li.selected {
|
||||
|
||||
background-color: var(--rouge-fonce);
|
||||
color: var(--blanc);
|
||||
border: 0.125rem solid var(--noir-clair);
|
||||
}
|
||||
|
||||
#tagsList,
|
||||
#narrowingTags {
|
||||
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
#tagsList li.station,
|
||||
#narrowingTags li.station {
|
||||
|
||||
order: 1;
|
||||
}
|
||||
|
||||
#tagsList li.station,
|
||||
#narrowingTags li.station {
|
||||
|
||||
background-image: url("logo.png");
|
||||
background-repeat: no-repeat;
|
||||
background-position: left middle;
|
||||
background-size: contain;
|
||||
padding-left: 2em;
|
||||
order: 1;
|
||||
}
|
||||
|
||||
#narrowingTags li.selectable {
|
||||
|
||||
background-color: var(--noir-fonce);
|
||||
color: var(--rouge-fonce);
|
||||
border: 0.125rem solid var(--noir-clair);
|
||||
}
|
||||
|
||||
#videosList > li {
|
||||
|
||||
background: var(--noir-clair);
|
||||
border-color: var(--rouge);
|
||||
border-style: solid;
|
||||
}
|
||||
|
||||
.video-title,
|
||||
.video-title a,
|
||||
.video-title a:visited {
|
||||
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
text-decoration: none;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
#videosList .thumbnail {
|
||||
|
||||
background-color: var(--noir-complet);
|
||||
}
|
||||
|
||||
#videosList > li ul.tags li a,
|
||||
#videosList > li ul.tags li a:visited {
|
||||
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
#videosList > li ul.tags li.selectable a,
|
||||
#videosList > li ul.tags li.selectable a:visited {
|
||||
|
||||
color: var(--blanc-semi-transparent);
|
||||
}
|
||||
|
||||
#videosList > li ul.tags li.selectable a:hover {
|
||||
|
||||
color: var(--blanc-fort);
|
||||
}
|
||||
|
||||
#videosList > li ul.tags li.selected a,
|
||||
#videosList > li ul.tags li.selected a:visited {
|
||||
|
||||
color: var(--blanc-fort);
|
||||
}
|
||||
|
||||
article {
|
||||
|
||||
background: var(--noir-clair);
|
||||
}
|
||||
|
||||
article video {
|
||||
|
||||
background: black;
|
||||
}
|
||||
|
||||
|
||||
article .video-title {
|
||||
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#successMsg {
|
||||
|
||||
opacity: 0;
|
||||
transition: opacity 1s;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1 @@
|
|||
.vjs-theme-forest{--vjs-theme-forest--primary:#6fb04e;--vjs-theme-forest--secondary:#fff}.vjs-theme-forest.vjs-big-play-button:focus,.vjs-theme-forest:hover .vjs-big-play-button{background-color:transparent;background:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='88' height='88' fill='%236fb04e'%3E%3Cpath fill-rule='evenodd' d='M44 88C19.738 88 0 68.262 0 44S19.738 0 44 0s44 19.738 44 44-19.738 44-44 44zm0-85C21.393 3 3 21.393 3 44c0 22.608 18.393 41 41 41s41-18.392 41-41C85 21.393 66.607 3 44 3zm16.063 43.898L39.629 60.741a3.496 3.496 0 01-3.604.194 3.492 3.492 0 01-1.859-3.092V30.158c0-1.299.712-2.483 1.859-3.092a3.487 3.487 0 013.604.194l20.433 13.843a3.497 3.497 0 01.001 5.795zm-1.683-3.311L37.946 29.744a.49.49 0 00-.276-.09.51.51 0 00-.239.062.483.483 0 00-.265.442v27.685c0 .262.166.389.265.442.1.053.299.118.515-.028L58.38 44.414A.489.489 0 0058.6 44a.49.49 0 00-.22-.413z'/%3E%3C/svg%3E")}.vjs-theme-forest .vjs-big-play-button{width:88px;height:88px;background:none;background-repeat:no-repeat;background-position:50%;background:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='88' height='88' fill='%23fff'%3E%3Cpath fill-rule='evenodd' d='M44 88C19.738 88 0 68.262 0 44S19.738 0 44 0s44 19.738 44 44-19.738 44-44 44zm0-85C21.393 3 3 21.393 3 44c0 22.608 18.393 41 41 41s41-18.392 41-41C85 21.393 66.607 3 44 3zm16.063 43.898L39.629 60.741a3.496 3.496 0 01-3.604.194 3.492 3.492 0 01-1.859-3.092V30.158c0-1.299.712-2.483 1.859-3.092a3.487 3.487 0 013.604.194l20.433 13.843a3.497 3.497 0 01.001 5.795zm-1.683-3.311L37.946 29.744a.49.49 0 00-.276-.09.51.51 0 00-.239.062.483.483 0 00-.265.442v27.685c0 .262.166.389.265.442.1.053.299.118.515-.028L58.38 44.414A.489.489 0 0058.6 44a.49.49 0 00-.22-.413z'/%3E%3C/svg%3E");border:none;top:50%;left:50%;margin-top:-44px;margin-left:-44px;color:purple}.vjs-theme-forest .vjs-big-play-button .vjs-icon-placeholder{display:none}.vjs-theme-forest .vjs-button>.vjs-icon-placeholder:before{line-height:1.55}.vjs-theme-forest .vjs-control:not(.vjs-disabled):not(.vjs-time-control):hover{color:var(--vjs-theme-forest--primary);text-shadow:var(--vjs-theme-forest--secondary) 1px 0 10px}.vjs-theme-forest .vjs-control-bar{background:none;margin-bottom:1em;padding-left:1em;padding-right:1em}.vjs-theme-forest .vjs-play-control{font-size:.8em}.vjs-theme-forest .vjs-play-control .vjs-icon-placeholder:before{background-color:var(--vjs-theme-forest--secondary);height:1.5em;width:1.5em;margin-top:.2em;border-radius:1em;color:var(--vjs-theme-forest--primary)}.vjs-theme-forest .vjs-play-control:hover .vjs-icon-placeholder:before{background-color:var(--vjs-theme-forest--primary);color:var(--vjs-theme-forest--secondary)}.vjs-theme-forest .vjs-mute-control{display:none}.vjs-theme-forest .vjs-volume-panel{margin-left:.5em;margin-right:.5em;padding-top:.3em}.vjs-theme-forest .vjs-volume-bar.vjs-slider-horizontal,.vjs-theme-forest .vjs-volume-panel,.vjs-theme-forest .vjs-volume-panel.vjs-volume-panel-horizontal.vjs-slider-active,.vjs-theme-forest .vjs-volume-panel.vjs-volume-panel-horizontal:hover,.vjs-theme-forest .vjs-volume-panel:active .vjs-volume-control.vjs-volume-horizontal,.vjs-theme-forest .vjs-volume-panel:hover,.vjs-theme-forest .vjs-volume-panel:hover .vjs-volume-control.vjs-volume-horizontal{width:3em}.vjs-theme-forest .vjs-volume-level:before{font-size:1em}.vjs-theme-forest .vjs-volume-panel .vjs-volume-control{opacity:1;width:100%;height:100%}.vjs-theme-forest .vjs-volume-bar{background-color:transparent;margin:0}.vjs-theme-forest .vjs-slider-horizontal .vjs-volume-level{height:100%}.vjs-theme-forest .vjs-volume-bar.vjs-slider-horizontal{margin-top:0;margin-bottom:0;height:100%}.vjs-theme-forest .vjs-volume-bar:before{content:"";z-index:0;width:0;height:0;position:absolute;top:0;left:0;border-left:3em solid transparent;border-bottom:2em solid var(--vjs-theme-forest--primary);border-right:0 solid transparent;border-top:0 solid transparent}.vjs-theme-forest .vjs-volume-level{overflow:hidden;background-color:transparent}.vjs-theme-forest .vjs-volume-level:before{content:"";z-index:1;width:0;height:0;position:absolute;top:0;left:0;border-left:3em solid transparent;border-bottom:2em solid var(--vjs-theme-forest--secondary);border-right:0 solid transparent;border-top:0 solid transparent}.vjs-theme-forest .vjs-progress-control:hover .vjs-progress-holder{font-size:1em}.vjs-theme-forest .vjs-play-progress:before{display:none}.vjs-theme-forest .vjs-progress-holder{border-radius:.2em;height:.5em;margin:0}.vjs-theme-forest .vjs-load-progress,.vjs-theme-forest .vjs-load-progress div,.vjs-theme-forest .vjs-play-progress{border-radius:.2em}
|
|
@ -0,0 +1,250 @@
|
|||
body {
|
||||
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
header {
|
||||
|
||||
overflow: hidden;
|
||||
padding: 1rem 0.666rem 1.333rem;
|
||||
margin-bottom: 2rem;
|
||||
|
||||
}
|
||||
|
||||
header > * {
|
||||
|
||||
font-size: 1.5rem;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
header > .sitetitle {
|
||||
|
||||
margin-bottom: 0.25rem;
|
||||
}
|
||||
|
||||
header > .sitetitle span {
|
||||
|
||||
border-bottom-style: solid;
|
||||
border-bottom-color: var(--pink);
|
||||
}
|
||||
|
||||
header .usp {
|
||||
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
main {
|
||||
|
||||
width: 95%;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
body.home main {
|
||||
|
||||
display: grid;
|
||||
grid-gap: 1rem 1rem;
|
||||
grid-auto-flow: row;
|
||||
grid-template-columns: 998px auto;
|
||||
grid-template-areas: "c m";
|
||||
}
|
||||
|
||||
body.home main > #menu {
|
||||
|
||||
grid-area: m;
|
||||
}
|
||||
|
||||
body.home main > ul#videosList {
|
||||
|
||||
grid-area: c;
|
||||
}
|
||||
|
||||
|
||||
aside#menu > div {
|
||||
|
||||
position: sticky;
|
||||
top: 2rem;
|
||||
}
|
||||
|
||||
#pinFilter ul {
|
||||
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
font-size: 3rem;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
#pinFilter ul li a span {
|
||||
|
||||
display: none;
|
||||
}
|
||||
|
||||
#pinFilter ul li a {
|
||||
|
||||
display: inline-block;
|
||||
height: 3rem;
|
||||
width: 3rem;
|
||||
border: 1px solid red;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
#pinFilter ul li#filter_pinned a {
|
||||
|
||||
background-image: url("font-awesome/hdd.svg");
|
||||
background-position: center center;
|
||||
background-size: 2.5rem;
|
||||
}
|
||||
|
||||
#pinFilter ul li#filter_notpinned a {
|
||||
|
||||
background-image: url("font-awesome/cloud.svg");
|
||||
background-position: center center;
|
||||
background-size: 2.5rem;
|
||||
}
|
||||
|
||||
#pinFilter ul li#filter_both a {
|
||||
|
||||
background-image: url("font-awesome/hdd.svg"),
|
||||
url("font-awesome/cloud.svg");
|
||||
background-position: bottom 0.25rem left 0.25rem,
|
||||
top 0.25rem right 0.25rem;
|
||||
background-size: 1.75rem,
|
||||
1.75rem;
|
||||
|
||||
}
|
||||
|
||||
#tagsList li,
|
||||
#narrowingTags li {
|
||||
|
||||
padding: 0.125rem 0.5rem;
|
||||
margin: 0.25rem 0.25rem;
|
||||
}
|
||||
|
||||
#videosList {
|
||||
|
||||
display: grid;
|
||||
grid-gap: 1rem 1rem;
|
||||
grid-auto-flow: row;
|
||||
grid-template-columns: 322px 322px 322px;
|
||||
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
justify-content: center;
|
||||
align-content: start
|
||||
}
|
||||
|
||||
#videosList > li {
|
||||
|
||||
border-radius: 0.25rem;
|
||||
border-width: 1px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#videosList .thumbnail {
|
||||
|
||||
text-align: center;
|
||||
height: 180px;
|
||||
margin-top: 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
#videosList .thumbnail img {
|
||||
|
||||
max-height: 180px;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
#videosList .video-title {
|
||||
|
||||
padding: 0.5rem 1rem;
|
||||
}
|
||||
|
||||
#videosList > li ul.tags {
|
||||
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
#videosList > li ul.tags li {
|
||||
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
#videosList > li ul.tags li:after {
|
||||
|
||||
content: ", ";
|
||||
}
|
||||
|
||||
#videosList > li ul.tags li:last-of-type:after {
|
||||
|
||||
content: "";
|
||||
}
|
||||
|
||||
article {
|
||||
|
||||
border-radius: 0.25rem;
|
||||
width: 58.3%;
|
||||
margin: auto;
|
||||
overflow: hidden;
|
||||
|
||||
}
|
||||
|
||||
article video {
|
||||
|
||||
width: 100%;
|
||||
max-height: calc(100vh - 14rem);
|
||||
}
|
||||
|
||||
article .video-title {
|
||||
|
||||
padding: 1rem 1rem;
|
||||
font-size: 1.25rem;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
form.add-video {
|
||||
|
||||
position: absolute;
|
||||
top: 0.50rem;
|
||||
right: 0.50rem;
|
||||
}
|
||||
|
||||
|
||||
form.add-video input {
|
||||
|
||||
height: 2rem;
|
||||
padding: 0.25rem 0.5rem;
|
||||
box-sizing: border-box;
|
||||
border-width: 0.125rem;
|
||||
border-radius: 0.5rem;
|
||||
|
||||
}
|
||||
|
||||
form label {
|
||||
|
||||
display: none;
|
||||
|
||||
}
|
||||
|
||||
form label input {
|
||||
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
form.add-video .confirmation {
|
||||
|
||||
margin: 0.5rem 0;
|
||||
font-size: 0.85rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
footer {
|
||||
|
||||
display: none;
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 9.6 KiB |
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,82 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>_CHANNEL_ : _TITLE_ [BunkerBOX]</title>
|
||||
<link rel="icon" type="image/png" href="_IPFSROOT_/styles/logo.png" />
|
||||
<link rel="stylesheet" href="_IPFSROOT_/styles/video-js.css" type="text/css" />
|
||||
<link rel="stylesheet" href="_IPFSROOT_/styles/forest.css" type="text/css" />
|
||||
<link rel="stylesheet" href="_IPFSROOT_/styles/decoration.css" type="text/css" />
|
||||
<link rel="stylesheet" href="_IPFSROOT_/styles/layout.css" type="text/css" />
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<h6>
|
||||
<a href="https://crowdbunker.com/v/_VUID_" target="bunker"> "<span>BunkerBOX</span>"</a> /ipfs/
|
||||
</h6>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<center>
|
||||
<div class="row justify-center">
|
||||
<video
|
||||
id="vbunk"
|
||||
class="video-js vjs-theme-forest"
|
||||
controls
|
||||
preload="auto"
|
||||
width="auto" height="auto"
|
||||
poster="_IPFSROOT_/_VUID_.jpg"
|
||||
|
||||
>
|
||||
<source src="_IPFSROOT_/_VUID_.m3u8" type="application/x-mpegURL" />
|
||||
<p class="vjs-no-js">
|
||||
Activer JavaScript SVP
|
||||
</p>
|
||||
</video>
|
||||
</div>
|
||||
</center>
|
||||
<article>
|
||||
<h1 class="video-title">
|
||||
_CHANNEL_ : _TITLE_
|
||||
</h1>
|
||||
</article>
|
||||
|
||||
<center>
|
||||
<div id="videosList"><div class="wrapper"></div></div>
|
||||
</center>
|
||||
|
||||
<h6>
|
||||
powered by <a href="https://astroport.com"><span>"</span>Astroport<span>"</span></a>
|
||||
</h6>
|
||||
|
||||
</main>
|
||||
</body>
|
||||
|
||||
<script src="_IPFSROOT_/js/video.min.js"></script>
|
||||
<script src="_IPFSROOT_/js/jquery.min.js"></script>
|
||||
<script src="_IPFSROOT_/js/pagination.min.js"></script>
|
||||
<link rel="stylesheet" href="_IPFSROOT_/styles/pagination.css" />
|
||||
<script>
|
||||
var player = videojs('vbunk', {
|
||||
autoplay: 'muted'
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<script>
|
||||
$.getJSON('./history.json', function (json) {
|
||||
$('#videosList').pagination({
|
||||
dataSource: json.Videos,
|
||||
pageSize: 1,
|
||||
callback: function(data, pagination) {
|
||||
var wrapper = $('#videosList .wrapper').empty();
|
||||
$.each(data, function (i, f) {
|
||||
$('#videosList .wrapper').append('<ul><li>' + f.link + '</li></ul>');
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
</html>
|
Loading…
Reference in New Issue