cabana: fix bugs and refactor a bit of can-frame offset code, improving experience for panda users.

main
Andy Haden 2017-07-11 18:10:31 -07:00
parent 023736c5ad
commit 4939892761
7 changed files with 66 additions and 51 deletions

View File

@ -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
});
}

View File

@ -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() {

View File

@ -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;

View File

@ -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;

View File

@ -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 {
<HLS
className={css(Styles.hls)}
source={Video.videoUrlForRouteUrl(this.props.url)}
startTime={this.nearestFrameTime()}
startTime={this.props.userSeekTime}
playbackSpeed={1}
onVideoElementAvailable={this.onVideoElementAvailable}
playing={this.props.playing}
@ -144,7 +136,7 @@ export default class RouteVideoSync extends Component {
onRestart={this.onHlsRestart} />
<RouteSeeker
className={css(Styles.seekBar)}
nearestFrameTime={this.nearestFrameTime()}
nearestFrameTime={this.props.userSeekTime}
segmentProgress={this.segmentProgress}
secondsLoaded={this.props.secondsLoaded}
segmentIndices={this.props.segmentIndices}

View File

@ -41,9 +41,8 @@ export default class Explorer extends Component {
segmentIndices: [],
shouldShowAddSignal: true,
userSeekIndex: 0,
userSeekRatio: 0,
userSeekTime: 0,
playing: this.props.autoplay,
userSeekTime: props.currentParts[0] * 60,
playing: props.autoplay,
signals: {}
};
this.onSignalPlotPressed = this.onSignalPlotPressed.bind(this);
@ -185,13 +184,10 @@ export default class Explorer extends Component {
}
}
if(nextProps.partsLoaded !== this.props.partsLoaded && !nextMessage) {
let userSeekRatio = this.state.userSeekRatio;
const nextSecondsLoaded = this.secondsLoadedRouteRelative(nextProps.currentParts);
userSeekRatio = (userSeekRatio * this.secondsLoaded()) / nextSecondsLoaded;
this.setState({userSeekRatio});
if(JSON.stringify(nextProps.currentParts) !== JSON.stringify(this.props.currentParts)) {
const {userSeekTime} = this.state;
const nextSeekTime = (userSeekTime - this.props.currentParts[0] * 60) + nextProps.currentParts[0] * 60;
this.setState({userSeekTime: nextSeekTime});
}
}
@ -251,42 +247,50 @@ export default class Explorer extends Component {
}
resetSegment() {
this.setState({segment: [], segmentIndices: [], userSeekIndex: 0, userSeekTime: 0})
const {segment, segmentIndices} = this.state;
if(segment.length > 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 ?
<div className={css(CommonStyles.button, Styles.resetSegment)}
onClick={() => this.resetSegment()}>
onClick={() => {this.resetSegment()}}>
<p>Reset Segment</p>
</div>
: null}

View File

@ -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) {