diff --git a/src/CanExplorer.js b/src/CanExplorer.js index 5893ba9..2a7ac40 100644 --- a/src/CanExplorer.js +++ b/src/CanExplorer.js @@ -146,7 +146,7 @@ export default class CanExplorer extends Component { prevMsgEntries = {}; } - const {dbc, dbcFilename, route, firstCanTime} = this.state; + const {dbc, dbcFilename, route, firstCanTime, canFrameOffset} = this.state; var worker = new CanFetcher(); worker.onmessage = (e) => { @@ -196,7 +196,7 @@ export default class CanExplorer extends Component { worker.postMessage({dbcText: dbc.text(), base: route.url, num: part, - canStartTime: firstCanTime, + canStartTime: firstCanTime - canFrameOffset, prevMsgEntries }); } diff --git a/src/api/routes.js b/src/api/routes.js index 781a133..595e183 100644 --- a/src/api/routes.js +++ b/src/api/routes.js @@ -47,7 +47,29 @@ const DEMO_ROUTES = { "start_lng": -122.465, "start_time": "2017-06-30T17:37:49", "url": "https://chffrprivate.blob.core.windows.net/chffrprivate3/v2/b67ff0c1d78774da/c130d5eaf04518c4d08ede29efbd519b_2017-06-30--17-37-49" - } + }, + "2017-07-10--19-11-08": { // elikorh panda route with bad offset + "can": true, + "device_type": 2, + "end_geocode": "Fargo", + "end_lat": 46.9041, + "end_lng": -96.8059, + "end_time": "2017-07-10T19:19:34", + "fullname": "03ad84b839400fdb|2017-07-10--19-11-08", + "len": 5.4562, + "maxcamera": 8, + "maxlog": 8, + "movie": true, + "piececount": 8, + "proccamera": 8, + "proclog": 8, + "sig_path": "03ad84b839400fdb/29176323acf8f30b6a09c188d8a3edb9_2017-07-10--19-11-08", + "start_geocode": "Fargo", + "start_lat": 46.8565, + "start_lng": -96.8426, + "start_time": "2017-07-10T19:11:08", + "url": "https://chffrprivate.blob.core.windows.net/chffrprivate3/v2/03ad84b839400fdb/29176323acf8f30b6a09c188d8a3edb9_2017-07-10--19-11-08" + } }; function getCommaAccessToken() { diff --git a/src/components/HLS.js b/src/components/HLS.js index b600155..b39075a 100644 --- a/src/components/HLS.js +++ b/src/components/HLS.js @@ -44,8 +44,7 @@ export default class HLS extends Component { this.videoElement.addEventListener('seeking', () => { if(!this.props.playing) { this.props.onLoadStart(); - const progress = this.props.segmentProgress(this.videoElement.currentTime); - this.props.onPlaySeek(progress); + this.props.onPlaySeek(this.videoElement.currentTime); } }); let shouldInitVideoTime = true; diff --git a/src/components/RouteSeeker.js b/src/components/RouteSeeker.js index b9594a0..a74ec55 100644 --- a/src/components/RouteSeeker.js +++ b/src/components/RouteSeeker.js @@ -156,7 +156,7 @@ export default class RouteSeeker extends Component { if(newRatio >= 0) { this.updateSeekedBar(newRatio); - this.props.onPlaySeek(newRatio); + this.props.onPlaySeek(currentTime); } }, 30); let {ratio} = this.state; diff --git a/src/components/RouteVideoSync.js b/src/components/RouteVideoSync.js index c810ad8..a80266d 100644 --- a/src/components/RouteVideoSync.js +++ b/src/components/RouteVideoSync.js @@ -22,7 +22,7 @@ export default class RouteVideoSync extends Component { onUserSeek: PropTypes.func.isRequired, onPlay: PropTypes.func.isRequired, onPause: PropTypes.func.isRequired, - userSeekRatio: PropTypes.number.isRequired + userSeekTime: PropTypes.number.isRequired }; constructor(props) { @@ -53,17 +53,9 @@ export default class RouteVideoSync extends Component { } } - nearestFrameTime() { - const {userSeekTime, message, canFrameOffset, firstCanTime} = this.props; - if(!message) { - return this.ratioTime(this.props.userSeekRatio); - } - return canFrameOffset + this.props.userSeekTime; - } - nearestFrameUrl() { const {url} = this.props; - const sec = Math.round(this.nearestFrameTime()); + const sec = Math.round(this.props.userSeekTime); return cameraPath(url, sec); } @@ -107,7 +99,7 @@ export default class RouteVideoSync extends Component { onUserSeek(ratio) { /* ratio in [0,1] */ - const funcSeekToRatio = () => this.props.onUserSeek(ratio); + const funcSeekToRatio = () => this.props.onUserSeek(this.ratioTime(ratio)); if(ratio == 0) { this.setState({shouldRestartHls: true}, funcSeekToRatio); @@ -130,7 +122,7 @@ export default class RouteVideoSync extends Component { 0 || segmentIndices.length > 0) { + this.setState({segment: [], segmentIndices: [], userSeekIndex: 0, userSeekTime: 0}) + } } showAddSignal() { this.setState({shouldShowAddSignal: true}) } - indexFromSeekRatio(ratio) { + indexFromSeekTime(time) { // returns index guaranteed to be in [0, entries.length - 1] const {entries} = this.props.messages[this.props.selectedMessage]; const {segmentIndices} = this.state; let segmentLength, offset; if(segmentIndices.length === 2) { - offset = segmentIndices[0]; - segmentLength = segmentIndices[1] - segmentIndices[0]; + for(let i = segmentIndices[0]; i <= segmentIndices[1]; i++) { + if(entries[i].relTime >= time) { + return i; + } + } + return segmentIndices[1]; } else { - offset = 0; - segmentLength = entries.length; + for(let i = 0; i < entries.length; i++) { + if(entries[i].relTime >= time) { + return i; + } + } + return entries.length - 1; } - - return Math.min(entries.length - 1, offset + Math.round(ratio * (segmentLength - 1))); } - onUserSeek(ratio) { - this.setState({userSeekRatio: ratio}); + onUserSeek(time) { + this.setState({userSeekTime: time}); const message = this.props.messages[this.props.selectedMessage]; if(!message) { - const seekTime = ratio * this.secondsLoaded() + this.startOffset(); - this.props.onUserSeek(seekTime); - this.props.onSeek(0, ratio * this.secondsLoaded() + this.startOffset()); + this.props.onUserSeek(time); + this.props.onSeek(0, time); return; } const {entries} = message; - const userSeekIndex = this.indexFromSeekRatio(ratio); + const userSeekIndex = this.indexFromSeekTime(time); const seekTime = entries[userSeekIndex].relTime; this.setState({userSeekIndex, userSeekTime: seekTime}); @@ -294,16 +298,16 @@ export default class Explorer extends Component { this.props.onSeek(userSeekIndex, seekTime); } - onPlaySeek(ratio) { + onPlaySeek(time) { const message = this.props.messages[this.props.selectedMessage]; if(!message) { - this.props.onSeek(0, ratio * this.secondsLoaded() + this.startOffset()); + this.props.onSeek(0, time); return; } const {entries} = message - const seekIndex = this.indexFromSeekRatio(ratio); + const seekIndex = this.indexFromSeekTime(time); const seekTime = entries[seekIndex].relTime; this.props.onSeek(seekIndex, seekTime); @@ -320,7 +324,6 @@ export default class Explorer extends Component { this.props.onUserSeek(time); this.setState({userSeekIndex, - userSeekRatio: (userSeekIndex) / entries.length, userSeekTime: time}); } @@ -368,7 +371,7 @@ export default class Explorer extends Component { startTime = entries[0].relTime; } - return canFrameOffset + startTime; + return startTime; } onVideoClick() { @@ -459,12 +462,11 @@ export default class Explorer extends Component { onUserSeek={this.onUserSeek} onPlay={this.onPlay} onPause={this.onPause} - userSeekRatio={this.state.userSeekRatio} userSeekTime={this.state.userSeekTime} /> {this.state.segment.length > 0 ?
this.resetSegment()}> + onClick={() => {this.resetSegment()}}>

Reset Segment

: null} diff --git a/src/workers/can-offset-finder.worker.js b/src/workers/can-offset-finder.worker.js index d3cb719..8510cef 100644 --- a/src/workers/can-offset-finder.worker.js +++ b/src/workers/can-offset-finder.worker.js @@ -9,7 +9,7 @@ function calcCanFrameOffset(firstCanPart, partCanTimes) { const firstPartLastCanTime = partCanTimes[partCanTimes.length - 1]; return (60 * firstCanPart - - (60 - (firstPartLastCanTime - firstCanTime))); + + (60 - (firstPartLastCanTime - firstCanTime))); } async function fetchCanTimes(base, part) {