Merge pull request #23 from CyberShadow/pull-20190727-205645

More fixes
This commit is contained in:
Ali Zemani 2019-08-03 11:06:21 +04:30 committed by GitHub
commit 114d029e18
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 84 additions and 84 deletions

View file

@ -34,6 +34,11 @@ var segmentGroups = bv.segmentGroups;
// Persistent state
var ls = window.localStorage || {};
if (!('initialized' in ls)) {
for (let k in bv.stateHistory)
ls["persistentState_" + k] = JSON.stringify(bv.stateHistory[k]);
ls['initialized'] = 't';
}
function msToString(ms) {
return new Date(ms).toUTCString().split(' ')[4];
@ -55,9 +60,9 @@ function preconditionToJS(cond) {
} else if (cond[0] == 'eql' && cond.length == 3) {
return '(' + cond.slice(1).map(preconditionToJS).join(' == ') + ')';
} else if (cond === false) {
return false;
return 'false';
} else if (cond === true) {
return true;
return 'true';
} else if (typeof cond === 'string') {
return JSON.stringify(cond);
} else {
@ -91,10 +96,6 @@ function resolveSegmentGroup(sg) {
if (v.segmentGroup) {
results.push(resolveSegmentGroup(v.segmentGroup));
} else if (v.segment) {
// TODO: does the included precondition override or
// complement the segment precondition?
if (!checkPrecondition(v.segment))
continue;
results.push(v.segment);
} else {
if (!checkPrecondition(v))
@ -110,7 +111,7 @@ function resolveSegmentGroup(sg) {
/// There will be exactly one segment for any timestamp within the video file.
function getSegmentId(ms) {
for (const [k, v] of Object.entries(segmentMap.segments)) {
if (ms >= v.startTimeMs && ms < v.endTimeMs) {
if (ms >= v.startTimeMs && (!v.endTimeMs || ms < v.endTimeMs)) {
return k;
}
}
@ -154,25 +155,15 @@ function addItem(ul, text, url) {
var nextChoice = -1;
var nextSegment = null;
function setNextSegment(segmentId, comment) {
console.log('setNextSegment', segmentId, comment);
nextSegment = segmentId;
nextChoice = -1;
var ul = newList("nextSegment");
var caption = 'nextSegment: ' + segmentId;
addItem(ul, comment ? caption + ' (' + comment + ')' : caption,
'javascript:playSegment("' + segmentId + '")');
}
function addZones(segmentId) {
var ul = newList("interactionZones");
let caption = 'currentSegment(' + segmentId + ')';
addItem(ul, caption, 'javascript:playSegment("' + segmentId + '")');
var v = segmentMap.segments[segmentId];
if (v && v.ui && v.ui.interactionZones) {
var segment = segmentMap.segments[segmentId];
if (segment && segment.ui && segment.ui.interactionZones) {
var index = 0;
for (var z of v.ui.interactionZones) {
for (var z of segment.ui.interactionZones) {
var startMs = z[0];
var stopMs = z[1];
let caption = segmentId + ' interactionZone ' + index;
@ -182,16 +173,14 @@ function addZones(segmentId) {
}
ul = newList("nextSegments");
let defaultSegmentId = null;
for (const [k, v] of Object.entries(segmentMap.segments[segmentId].next)) {
let caption = k;
if (segmentMap.segments[segmentId].defaultNext == k) {
caption = '[' + caption + ']';
defaultSegmentId = k;
if (segment) {
for (const [k, v] of Object.entries(segment.next)) {
let caption = k;
if (segment.defaultNext == k)
caption = '[' + caption + ']';
addItem(ul, caption, 'javascript:playSegment("' + k + '")');
}
addItem(ul, caption, 'javascript:playSegment("' + k + '")');
}
setNextSegment(defaultSegmentId);
}
var currentChoiceMoment = null;
@ -245,12 +234,14 @@ var timerId = 0;
var lastMs = 0;
var currentSegment;
var lastSegment = null;
var prevSegment = null; // for breadcrumbs
var segmentTransition = false;
var lastMoments = [];
function ontimeupdate(evt) {
var ms = getCurrentMs();
currentSegment = getSegmentId(ms);
let segment = segmentMap.segments[currentSegment];
if (timerId) {
clearTimeout(timerId);
@ -269,9 +260,10 @@ function ontimeupdate(evt) {
// Handle segment change
if (lastSegment != currentSegment) {
console.log('ontimeupdate', lastSegment, '->', currentSegment, ms, msToString(ms), seeked);
prevSegment = lastSegment;
lastSegment = currentSegment;
if (!seeked) {
if (playNextSegment()) {
if (!seeked && prevSegment) {
if (playNextSegment(prevSegment)) {
// playSegment decided to seek, which means that this
// currentSegment is invalid, and a recursive
// ontimeupdate invocation should have taken care of
@ -318,7 +310,7 @@ function ontimeupdate(evt) {
let hash = currentSegment;
// Pick the moment which starts closer to the current timestamp.
let bestMomentStart = segmentMap.segments[currentSegment].startTimeMs;
let bestMomentStart = segment ? segment.startTimeMs : 0;
for (let k in currentMoments) {
let m = currentMoments[k];
if (m.startMs > bestMomentStart) {
@ -333,7 +325,7 @@ function ontimeupdate(evt) {
}
// ontimeupdate resolution is about a second. Augment it using timer.
let nextEvent = segmentMap.segments[currentSegment].endTimeMs;
let nextEvent = segment ? segment.endTimeMs : 0;
for (let k in currentMoments) {
let m = currentMoments[k];
if (m.endMs < nextEvent)
@ -347,7 +339,8 @@ function ontimeupdate(evt) {
timerId = setTimeout(ontimeupdate, timeLeft);
}
function playNextSegment() {
function playNextSegment(prevSegment) {
let nextSegment = null;
if (nextChoice >= 0) {
let x = currentChoiceMoment.choices[nextChoice];
if (x.segmentId)
@ -357,19 +350,25 @@ function playNextSegment() {
else
nextSegment = null;
console.log('choice', nextChoice, 'nextSegment', nextSegment);
nextChoice = -1;
applyImpression(x.impressionData);
}
if (!nextSegment && prevSegment && prevSegment in segmentGroups)
nextSegment = resolveSegmentGroup(prevSegment);
if (!nextSegment && prevSegment && segmentMap.segments[prevSegment].defaultNext)
nextSegment = segmentMap.segments[prevSegment].defaultNext;
if (!nextSegment)
return false;
let breadcrumb = 'breadcrumb_' + nextSegment;
if (!(breadcrumb in ls))
ls[breadcrumb] = lastSegment;
ls[breadcrumb] = prevSegment;
segmentTransition = true;
let segment = nextSegment;
nextSegment = null;
if (segment)
return playSegment(segment, true);
return false;
return playSegment(nextSegment, true);
}
function jumpForward() {
@ -387,7 +386,7 @@ function jumpForward() {
if (interactionMs) {
seek(interactionMs);
} else {
playNextSegment();
playNextSegment(segmentId);
}
}
@ -544,14 +543,15 @@ function choice(choiceIndex) {
nextChoice = choiceIndex;
newList("choices");
if (!currentChoiceMoment.config.disableImmediateSceneTransition)
playNextSegment();
playNextSegment(prevSegment);
}
function applyImpression(impressionData) {
if (impressionData && impressionData.type == 'userState') {
for (const [variable, value] of Object.entries(impressionData.data.persistent)) {
console.log('persistentState set', variable, '=', value);
ls["persistentState_" + variable] = JSON.stringify(value);
let key = "persistentState_" + variable;
console.log('persistentState set', variable, '=', value, '(was', key in ls ? ls[key] : 'unset', ')');
ls[key] = JSON.stringify(value);
}
}
}
@ -569,6 +569,12 @@ function playSegment(segmentId, noSeek) {
return false;
}
function reset() {
ls.clear();
location.hash = '';
location.reload();
}
var lastHash = '';
function playHash(hash) {
// console.log('playHash', lastHash, '->', hash);

View file

@ -262,7 +262,7 @@ ul.controls-tips {
padding: 16px;
width: inherit;
margin: 0;
margin: 29px auto;
margin: 15px auto;
text-align: left;
}
@ -271,8 +271,8 @@ h2 {
font-size: 1em;
}
ul.file-tips li,
ul.controls-tips li {
ul.file-tips > li,
ul.controls-tips > li {
font-size: .45em;
}

View file

@ -34,22 +34,19 @@
<title>Bandersnatch Interactive Player</title>
<meta name="description"
content="With this online(html) video player you can watch Bandersnatch episode of Black Mirror interactively." />
<meta name="keywords" content="Bandersnatch,Bandersnatch Interactive Player,Interactive Player,whatch," />
content="Stand-alone open-source interactive HTML player for Black Mirror - Bandersnatch" />
<meta name="keywords" content="Bandersnatch,Bandersnatch Interactive Player,Interactive Player,watch," />
<script src="assets/bandersnatch.js"></script>
<script src="assets/SegmentMap.js"></script>
<script src="assets/scripts.js"></script>
<link rel="stylesheet" type="text/css" href="assets/styles.css">
<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-132739093-1"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag() { dataLayer.push(arguments); }
gtag('js', new Date());
gtag('config', 'UA-132739093-1');
// keep localizable strings out of scripts.js
function askReset() {
if (confirm('Are you sure you want to reset all choices, breadcrumbs, and watched scenes?'))
reset();
}
</script>
<link rel="stylesheet" type="text/css" href="assets/styles.css">
</head>
<body>
@ -60,12 +57,12 @@
<div class="file-area">
<div class="contact">
<p>
Developed by <a href="https://github.com/mehotkhan" target="_blank">Mehotkhan</a> ,for
info <a href="https://github.com/mehotkhan/BandersnatchInteractive"
target="_blank">https://github.com/mehotkhan/BandersnatchInteractive</a>
,<b>if you want some donation : my bitcoin wallet :</b>
<pr>1CxaCJbh4VMNicnpktsBVfnVU5xq4QYyHW</pr>
Authors:
<a href="https://github.com/joric/bandersnatch/">Original version</a> - <a href="https://github.com/joric/">joric</a> |
Web page, subtitles - <a href="https://github.com/mehotkhan">Mehotkhan</a> (<a href="bitcoin:1CxaCJbh4VMNicnpktsBVfnVU5xq4QYyHW">donate</a>) |
Many fixes, improvements, and everything else - <a href="https://github.com/CyberShadow">CyberShadow</a>
<br>
This player remembers your choices and watch history. <a href="javascript:askReset()">Click here to reset and start from scratch.</a>
</p>
</div>
<input id="fileinput" type="file">
@ -74,31 +71,30 @@
<span class="default">Select Bandersnatch video file ( 5:12:14 ) </span>
<span class="success">Great, your file is selected</span>
<ul class="file-tips">
<li>this player only work on google chrome ( on firefox dont work , codec problem,test
other browser ?)</li>
<li>download Bandersnatch video file ( 5:12:14 )</li>
<li>drag it on white box on page :)</li>
<li>Persian , English , Arabic , Spanish , Hebrew ,Portuguese ,Greek ,Turkish ,Polish ,Indonesian
subtitle available , if you want add another language
subtitle , tell me</li>
<li>to change subtitle : right click on video , enable show controls , after that . on
bottom,right you see
<span class="menu-item"></span> ,then you can subtitle section </li>
<li>Note : after change subtitle , disable show controls ,if dont disable it on full
screen video,you cant see
option selector</li>
<li>tested with Black.Mirror.Bandersnatch.2018.720p.WEB-DL.x264.DUAL.mkv file</li>
<li>This player is known to work only on Google Chrome or Chromium.</li>
<li>Obtain the Bandersnatch video file (duration should be 5:12:14).<br>
Tested with <code>Black.Mirror.Bandersnatch.2018.720p.WEB-DL.x264.DUAL.mkv</code>.</li>
<li>Drag it on top of this box (or click here to select it).</li>
<li>Subtitles in many languages are available.</li>
<li>To change the subtitle:
<ol>
<li>Right click on the video</li>
<li>Enable "Show controls"</li>
<li>Click on the <span class="menu-item"></span> in the bottom-right</li>
<li>Select the desired subtitle</li>
<li>You can now hide the player controls in the same way as step 1-2.</li>
</ol></li>
<li>Note: do not use the "full screen" button in the video player if you enable "Show controls".
Choice selection interface will not be visible if you do this.</li>
</ul>
<ul class="controls-tips">
<h6>controls tips</h6>
<h6>Keyboard controls</h6>
<li><kbd>F</kbd> - Toggle fullscreen</li>
<li><kbd>R</kbd> - Restart video</li>
<li><kbd></kbd> - Jump to the next segment (or to the next interaction zone)</li>
<li><kbd></kbd> - Jump to the previous segment (or interaction zone)</li>
<li><kbd></kbd> / <kbd></kbd> - Jump to the next / previous segment (or interaction zone)</li>
<li><kbd></kbd> / <kbd></kbd> - Speed up / slow down playback</li>
<li><kbd>Space</kbd> - Toggle play and pause</li>
</ul>
</div>
</div>
@ -127,8 +123,6 @@
src="subtitle/Czarne.lustro_.Bandersnatch.WEBRip.Netflix.pl.vtt">
<track label="Indonesian" kind="subtitles" srclang="en"
src="subtitle/Black.Mirror.Bandersnatch.2018.WEBRip.x264-NoGRP-Indonesian-vtt-sharp.vtt">
</video>
<div class="controls">
<div id="choiceCaption"></div>