Skip to content

Commit

Permalink
Krec ts & ffmpeg fix (#4)
Browse files Browse the repository at this point in the history
* krec-ts

* added ffmpeg null output; gitignore
  • Loading branch information
hatomist authored Nov 25, 2024
1 parent 308c16a commit 118affa
Show file tree
Hide file tree
Showing 9 changed files with 159 additions and 3 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,7 @@ out*/
# Rust
Cargo.lock
target/

# Node
krec-ts/node_modules/
krec-ts/src/generated/
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,5 @@ resolver = "2"

[workspace.package]

version = "0.2.7"
version = "0.2.8"
edition = "2021"
23 changes: 23 additions & 0 deletions krec-ts/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"name": "krec-ts",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"generate-proto": "pbjs -t static-module -w commonjs -o src/generated/proto.js ../proto/krec.proto && pbts -o src/generated/proto.d.ts src/generated/proto.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"description": "",
"dependencies": {
"@types/node": "^18.19.65",
"long": "^5.2.3",
"protobufjs": "^7.4.0"
},
"devDependencies": {
"@types/long": "^5.0.0",
"ts-node": "^10.9.2",
"typescript": "^5.8.0"
}
}
40 changes: 40 additions & 0 deletions krec-ts/src/example.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { KRec } from "./krec";
import { promises as fs } from "fs";
import { Long } from "protobufjs/minimal";

// Helper function to convert Long timestamp to Date
function longToDate(timestamp: Long): Date {
// Convert nanoseconds to milliseconds
const ms = Number(timestamp) / 1_000_000;
return new Date(ms);
}

// Helper function to format Long to number (safe for frame numbers)
function longToNumber(value: Long): number {
return Number(value);
}

async function main() {
const buffer = await fs.readFile("./test.krec");

const krec = await KRec.load(buffer);

console.log("Recording UUID:", krec.header.uuid);
console.log("Number of frames:", krec.frames.length);

if (krec.frames.length > 0) {
const frame = krec.frames[0];
console.log("First frame:", {
timestamp: longToDate(frame.videoTimestamp as Long).toISOString(),
frameNumber: longToNumber(frame.frameNumber as Long),
actuatorStates: frame.actuatorStates?.map(state => ({
online: state.online,
position: state.position,
velocity: state.velocity,
torque: state.torque
}))
});
}
}

main().catch(console.error);
Empty file added krec-ts/src/generated/.keep
Empty file.
67 changes: 67 additions & 0 deletions krec-ts/src/krec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { Reader } from "protobufjs";
import { krec } from "./generated/proto";

export class KRec {
header: krec.proto.IKRecHeader;
frames: krec.proto.IKRecFrame[];

constructor(header: krec.proto.IKRecHeader) {
this.header = header;
this.frames = [];
}

static async load(buffer: Buffer): Promise<KRec> {
let pos = 0;

// Read header length and decode header
if (buffer.length < 4) {
throw new Error(`File too short: ${buffer.length} bytes`);
}

const headerLen = buffer.readUInt32LE(0);
pos += 4;

if (pos + headerLen > buffer.length) {
throw new Error(
`Incomplete header data: need ${headerLen} bytes, have ${buffer.length - pos} bytes`
);
}

const header = krec.proto.KRecHeader.decode(
Reader.create(buffer.subarray(pos, pos + headerLen))
);
pos += headerLen;

const frames: krec.proto.IKRecFrame[] = [];

// Read frames
while (pos + 4 <= buffer.length) {
const frameLen = buffer.readUInt32LE(pos);
pos += 4;

if (pos + frameLen > buffer.length) {
throw new Error(
`Incomplete frame data: at position ${pos}, need ${frameLen} bytes, have ${
buffer.length - pos
} bytes remaining`
);
}

const frame = krec.proto.KRecFrame.decode(
Reader.create(buffer.subarray(pos, pos + frameLen))
);
pos += frameLen;
frames.push(frame);
}

if (pos !== buffer.length) {
throw new Error(
`Trailing data: ${buffer.length - pos} bytes remaining after position ${pos}`
);
}

const krecInstance = new KRec(header);
krecInstance.frames = frames;
return krecInstance;
}
}
14 changes: 14 additions & 0 deletions krec-ts/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"compilerOptions": {
"target": "es2018",
"module": "commonjs",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"outDir": "./dist",
"declaration": true
},
"include": ["src/**/*"],
"exclude": ["node_modules"]
}
2 changes: 1 addition & 1 deletion krec/bindings/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "maturin"

[project]
name = "bindings"
version = "0.1.4"
version = "0.1.5"
description = "Python bindings for KRec"
authors = [{ name = "Denys Bezmenov", email = "[email protected]" }]
requires-python = ">=3.7"
Expand Down
10 changes: 9 additions & 1 deletion src/ffmpeg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,15 @@ pub fn combine_with_video(

pub fn extract_from_video(video_path: &str, output_path: &str) -> Result<(), FFmpegError> {
let status = std::process::Command::new("ffmpeg")
.args(["-dump_attachment:t:0", output_path, "-i", video_path])
.args([
"-dump_attachment:t:0",
output_path,
"-i",
video_path,
"-f",
"null",
"/dev/null",
])
.status()
.map_err(|e| FFmpegError::FFmpeg(e.to_string()))?;

Expand Down

0 comments on commit 118affa

Please sign in to comment.