Rename project, crates, and binaries to open-360-link

This commit is contained in:
Lucas Oskorep committed 2026-10-27 11:27:30 -04:00
1 parent ef641ac31b
commit bbdcde3f0f
28 files changed
+219 -207

No files matched your search

@@ -1,16 +1,16 @@
[package]
name = "insta360-link-cli"
name = "open-360-link-cli"
version.workspace = true
edition.workspace = true
license.workspace = true
description = "Cross-platform CLI controller for Insta360 Link, Link 2, and Link 2C cameras"
description = "Open 360 Link: Cross-platform CLI controller for Insta360 Link, Link 2, and Link 2C cameras"
[[bin]]
name = "insta360-link-ctl"
name = "open-360-link-ctl"
path = "src/main.rs"
[dependencies]
insta360-link-protocol = { path = "../insta360-link-protocol" }
open-360-link-protocol = { path = "../open-360-link-protocol" }
clap.workspace = true
serde.workspace = true
serde_json.workspace = true
@@ -1,5 +1,5 @@
use clap::{ArgAction, Parser, Subcommand, ValueEnum};
use insta360_link_protocol::{
use open_360_link_protocol::{
list_connected_cameras, AudioCaptureMode, CameraModel, CompositionStyle, DeviceInfo,
DeviceStatus, DiscoveredCamera, ExtendFunction, FilterMode, ForbiddenAreaInfo, Gesture,
GestureFunction, HostPtzInfo, ImageOperation, Insta360CameraController, MockCameraTransport,
@@ -11,9 +11,9 @@ use std::process::ExitCode;
#[derive(Parser, Debug)]
#[command(
name = "insta360-link-ctl",
name = "open-360-link-ctl",
version,
about = "Cross-platform CLI controller for Insta360 Link, Link 2, and Link 2C cameras"
about = "Open 360 Link: Cross-platform CLI controller for Insta360 Link, Link 2, and Link 2C cameras"
)]
pub struct Cli {
/// Run against an in-memory simulated camera model instead of physical USB
@@ -1,16 +1,16 @@
[package]
name = "insta360-link-gui"
name = "open-360-link-gui"
version.workspace = true
edition.workspace = true
license.workspace = true
description = "Cross-platform pure-Rust desktop GUI controller for Insta360 Link, Link 2, and Link 2C"
description = "Open 360 Link: Cross-platform pure-Rust desktop GUI controller for Insta360 Link, Link 2, and Link 2C"
[[bin]]
name = "insta360-link-gui"
name = "open-360-link-gui"
path = "src/main.rs"
[dependencies]
insta360-link-protocol = { path = "../insta360-link-protocol" }
open-360-link-protocol = { path = "../open-360-link-protocol" }
eframe.workspace = true
egui.workspace = true
image = { version = "0.25", default-features = false, features = ["png"] }
@@ -7,7 +7,7 @@ mod video_engine;
use std::time::{Duration, Instant};
use eframe::egui::{self, Align2, Color32, FontId, Margin, Pos2, Rect, RichText, Rounding, Stroke, Vec2};
use insta360_link_protocol::{
use open_360_link_protocol::{
list_connected_cameras, CameraModel, DiscoveredCamera, Insta360CameraController,
MockCameraTransport, NusbTransport, PowerLineFrequency, VideoMode, VideoModeAuxData,
};
@@ -181,41 +181,41 @@ impl Insta360App {
if let Ok(ext) = self.controller.get_extend_function_status() {
for (func, en) in ext {
match func {
insta360_link_protocol::ExtendFunction::AiZoom => {
open_360_link_protocol::ExtendFunction::AiZoom => {
self.state.ai_zoom_enabled = en
}
insta360_link_protocol::ExtendFunction::AllGestures => {
open_360_link_protocol::ExtendFunction::AllGestures => {
self.state.enable_all_gestures = en
}
insta360_link_protocol::ExtendFunction::AutoTracking => {
open_360_link_protocol::ExtendFunction::AutoTracking => {
self.state.enable_auto_tracking = en
}
insta360_link_protocol::ExtendFunction::SingleTapTracking => {
open_360_link_protocol::ExtendFunction::SingleTapTracking => {
self.state.enable_single_tap_tracking = en
}
insta360_link_protocol::ExtendFunction::Hdr => self.state.hdr_enabled = en,
insta360_link_protocol::ExtendFunction::HorizontalMirror => {
open_360_link_protocol::ExtendFunction::Hdr => self.state.hdr_enabled = en,
open_360_link_protocol::ExtendFunction::HorizontalMirror => {
self.state.horizontal_mirror = en
}
insta360_link_protocol::ExtendFunction::VerticalMirror => {
open_360_link_protocol::ExtendFunction::VerticalMirror => {
self.state.vertical_mirror = en
}
insta360_link_protocol::ExtendFunction::VerticalMode => {
open_360_link_protocol::ExtendFunction::VerticalMode => {
self.state.vertical_resolution_mode = en
}
insta360_link_protocol::ExtendFunction::ForcedVertical => {
open_360_link_protocol::ExtendFunction::ForcedVertical => {
self.state.forced_vertical_lock = en
}
insta360_link_protocol::ExtendFunction::LowResolution => {
open_360_link_protocol::ExtendFunction::LowResolution => {
self.state.low_resolution_mode = en
}
insta360_link_protocol::ExtendFunction::SmartAdjustment => {
open_360_link_protocol::ExtendFunction::SmartAdjustment => {
self.state.smart_adjustment = en
}
insta360_link_protocol::ExtendFunction::StartupParams => {
open_360_link_protocol::ExtendFunction::StartupParams => {
self.state.startup_params_enabled = en
}
insta360_link_protocol::ExtendFunction::UltimatePrivacyMode => {
open_360_link_protocol::ExtendFunction::UltimatePrivacyMode => {
self.state.ultimate_privacy = en
}
_ => {}
@@ -231,11 +231,11 @@ impl Insta360App {
if let Ok(gestures) = self.controller.get_gesture_status() {
for (g, en) in gestures {
match g {
insta360_link_protocol::Gesture::Ok => self.state.use_gesture_ok = en,
insta360_link_protocol::Gesture::Palm => self.state.use_gesture_palm = en,
insta360_link_protocol::Gesture::LShape => self.state.use_gesture_l = en,
insta360_link_protocol::Gesture::VShape => self.state.use_gesture_v = en,
insta360_link_protocol::Gesture::Rock => self.state.use_gesture_rock = en,
open_360_link_protocol::Gesture::Ok => self.state.use_gesture_ok = en,
open_360_link_protocol::Gesture::Palm => self.state.use_gesture_palm = en,
open_360_link_protocol::Gesture::LShape => self.state.use_gesture_l = en,
open_360_link_protocol::Gesture::VShape => self.state.use_gesture_v = en,
open_360_link_protocol::Gesture::Rock => self.state.use_gesture_rock = en,
}
}
}
@@ -325,15 +325,15 @@ impl Insta360App {
.controller
.set_all_gestures_enabled(self.state.enable_all_gestures);
let _ = self.controller.set_gesture_enabled(
insta360_link_protocol::Gesture::Palm,
open_360_link_protocol::Gesture::Palm,
self.state.use_gesture_palm,
);
let _ = self.controller.set_gesture_enabled(
insta360_link_protocol::Gesture::VShape,
open_360_link_protocol::Gesture::VShape,
self.state.use_gesture_v,
);
let _ = self.controller.set_gesture_enabled(
insta360_link_protocol::Gesture::LShape,
open_360_link_protocol::Gesture::LShape,
self.state.use_gesture_l,
);
let _ = self
@@ -412,14 +412,14 @@ impl Insta360App {
)
.show(ctx, |ui| {
ui.horizontal_centered(|ui| {
// Left: Green Insta360 camera icon + "Insta360 Link Controller" title
// Left: Green camera icon + "Open 360 Link" title
ui.label(
RichText::new("📷")
.color(theme.brand_green)
.size(17.0_f32),
);
ui.label(
RichText::new("Insta360 Link Controller")
RichText::new("Open 360 Link")
.strong()
.size(14.5_f32)
.color(theme.text01),
@@ -1257,7 +1257,7 @@ impl Insta360App {
.changed()
{
let _ = self.controller.set_gesture_enabled(
insta360_link_protocol::Gesture::Palm,
open_360_link_protocol::Gesture::Palm,
self.state.use_gesture_palm,
);
}
@@ -1267,7 +1267,7 @@ impl Insta360App {
.changed()
{
let _ = self.controller.set_gesture_enabled(
insta360_link_protocol::Gesture::VShape,
open_360_link_protocol::Gesture::VShape,
self.state.use_gesture_v,
);
}
@@ -1277,7 +1277,7 @@ impl Insta360App {
.changed()
{
let _ = self.controller.set_gesture_enabled(
insta360_link_protocol::Gesture::LShape,
open_360_link_protocol::Gesture::LShape,
self.state.use_gesture_l,
);
}
@@ -1455,13 +1455,13 @@ impl Insta360App {
ui.label("Tracking Speed:");
egui::ComboBox::from_id_salt("tb_track_speed")
.selected_text(match self.state.track_speed {
insta360_link_protocol::TrackSpeed::Fast => {
open_360_link_protocol::TrackSpeed::Fast => {
"Quick"
}
insta360_link_protocol::TrackSpeed::Normal => {
open_360_link_protocol::TrackSpeed::Normal => {
"Ordinary"
}
insta360_link_protocol::TrackSpeed::Slow => {
open_360_link_protocol::TrackSpeed::Slow => {
"Slow"
}
})
@@ -1469,37 +1469,37 @@ impl Insta360App {
if ui
.selectable_value(
&mut self.state.track_speed,
insta360_link_protocol::TrackSpeed::Fast,
open_360_link_protocol::TrackSpeed::Fast,
"Quick",
)
.clicked()
{
let _ = self.controller.set_track_speed(
insta360_link_protocol::TrackSpeed::Fast,
open_360_link_protocol::TrackSpeed::Fast,
);
}
if ui
.selectable_value(
&mut self.state.track_speed,
insta360_link_protocol::TrackSpeed::Normal,
open_360_link_protocol::TrackSpeed::Normal,
"Ordinary",
)
.clicked()
{
let _ = self.controller.set_track_speed(
insta360_link_protocol::TrackSpeed::Normal,
open_360_link_protocol::TrackSpeed::Normal,
);
}
if ui
.selectable_value(
&mut self.state.track_speed,
insta360_link_protocol::TrackSpeed::Slow,
open_360_link_protocol::TrackSpeed::Slow,
"Slow",
)
.clicked()
{
let _ = self.controller.set_track_speed(
insta360_link_protocol::TrackSpeed::Slow,
open_360_link_protocol::TrackSpeed::Slow,
);
}
});
@@ -2307,9 +2307,9 @@ impl eframe::App for Insta360App {
let z_read = self.controller.get_zoom().unwrap_or(0);
let _ = self.controller.set_zoom(100);
let _ = self.controller.set_track_speed(insta360_link_protocol::TrackSpeed::Fast);
let _ = self.controller.set_track_speed(open_360_link_protocol::TrackSpeed::Fast);
let ts_fast = self.controller.get_track_speed().ok();
let _ = self.controller.set_track_speed(insta360_link_protocol::TrackSpeed::Normal);
let _ = self.controller.set_track_speed(open_360_link_protocol::TrackSpeed::Normal);
let ts_norm = self.controller.get_track_speed().ok();
let _ = self.controller.set_auto_exposure(true);
@@ -2370,7 +2370,7 @@ impl eframe::App for Insta360App {
let _ = self.controller.set_all_gestures_enabled(true);
let _ = self
.controller
.set_gesture_enabled(insta360_link_protocol::Gesture::Palm, true);
.set_gesture_enabled(open_360_link_protocol::Gesture::Palm, true);
let gest = self.controller.get_gesture_status().ok();
println!(
@@ -2569,16 +2569,16 @@ fn main() -> eframe::Result<()> {
// Matching webcam.qml: width: 1440, height: 714, minimumWidth: 1120, minimumHeight: 536
let native_options = eframe::NativeOptions {
viewport: egui::ViewportBuilder::default()
.with_app_id("insta360-link-controller")
.with_app_id("open-360-link")
.with_icon(build_app_icon())
.with_inner_size([1440.0_f32, 714.0_f32])
.with_min_inner_size([1120.0_f32, 536.0_f32])
.with_title("Insta360 Link Controller"),
.with_title("Open 360 Link"),
..Default::default()
};
eframe::run_native(
"Insta360 Link Controller",
"Open 360 Link",
native_options,
Box::new(|cc| Ok(Box::new(Insta360App::new(cc)))),
)
@@ -2,7 +2,7 @@ use egui::{
Align, Align2, Color32, Context, FontId, Grid, Layout, Pos2, Rect, RichText, Rounding,
ScrollArea, Sense, Stroke, TextEdit, Ui, Vec2,
};
use insta360_link_protocol::{
use open_360_link_protocol::{
AudioCaptureMode, CameraModel, CompositionStyle, ExposureCurve, FilterMode, HostPtzInfo,
ImageOperation, Insta360CameraController, PowerLineFrequency, TrackSpeed, UvcControlTransport,
Gesture,
@@ -1,7 +1,7 @@
#![allow(dead_code)]
use egui::{ColorImage, Pos2, TextureHandle};
pub use insta360_link_protocol::*;
pub use open_360_link_protocol::*;
use serde::{Deserialize, Serialize};
use std::path::PathBuf;
use std::time::Instant;
@@ -285,7 +285,7 @@ pub struct CameraAppState {
pub last_saved_settings: Option<PersistedAppSettings>,
}
/// User settings persisted across sessions in `~/.config/insta360-link-controller/settings.json`.
/// User settings persisted across sessions in `~/.config/open-360-link/settings.json`.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct PersistedAppSettings {
pub format_preset: VideoFormatPreset,
@@ -325,12 +325,10 @@ pub struct PersistedAppSettings {
}
impl PersistedAppSettings {
pub fn config_path() -> PathBuf {
fn base_config_dir() -> PathBuf {
if let Ok(xdg) = std::env::var("XDG_CONFIG_HOME") {
if !xdg.trim().is_empty() {
return PathBuf::from(xdg)
.join("insta360-link-controller")
.join("settings.json");
return PathBuf::from(xdg);
}
}
let home = std::env::var("HOME")
@@ -338,14 +336,29 @@ impl PersistedAppSettings {
.map(PathBuf::from)
.unwrap_or_else(|_| PathBuf::from("."));
home.join(".config")
.join("insta360-link-controller")
}
pub fn config_path() -> PathBuf {
Self::base_config_dir()
.join("open-360-link")
.join("settings.json")
}
pub fn load() -> Option<Self> {
let path = Self::config_path();
let data = std::fs::read_to_string(path).ok()?;
serde_json::from_str(&data).ok()
if let Ok(data) = std::fs::read_to_string(&path) {
if let Ok(parsed) = serde_json::from_str(&data) {
return Some(parsed);
}
}
// Automatic migration from legacy `~/.config/insta360-link-controller/settings.json`
let legacy = Self::base_config_dir()
.join("insta360-link-controller")
.join("settings.json");
let data = std::fs::read_to_string(legacy).ok()?;
let parsed: Self = serde_json::from_str(&data).ok()?;
parsed.save();
Some(parsed)
}
pub fn save(&self) {
File renamed without changes.
@@ -1,6 +1,6 @@
#![allow(dead_code)]
use insta360_link_protocol::{
use open_360_link_protocol::{
ct_selectors, pu_selectors, xu1_selectors, xu2_selectors, CameraModel, DiscoveredCamera,
MockCameraTransport, NusbTransport, TransportError, UvcControlPacketHeader,
UvcControlTransport, UvcRequest, UvcUnitIds,
@@ -3,7 +3,7 @@ use crate::state::{
SHUTTER_DENOM_LIST,
};
use egui::{Color32, ColorImage, Context, TextureHandle, TextureOptions};
use insta360_link_protocol::{TrackSpeed, UvcRect, VideoMode};
use open_360_link_protocol::{TrackSpeed, UvcRect, VideoMode};
use std::io::{Read, Write};
use std::path::{Path, PathBuf};
use std::process::{Child, ChildStdin, Command, Stdio};
@@ -1,9 +1,9 @@
[package]
name = "insta360-link-protocol"
name = "open-360-link-protocol"
version.workspace = true
edition.workspace = true
license.workspace = true
description = "Pure-Rust cross-platform UVC & Extension Unit protocol library for Insta360 Link, Link 2, and Link 2C webcams"
description = "Open 360 Link: Pure-Rust cross-platform UVC & Extension Unit protocol library for Insta360 Link, Link 2, and Link 2C webcams"
[dependencies]
thiserror.workspace = true
@@ -1,4 +1,4 @@
use insta360_link_protocol::*;
use open_360_link_protocol::*;
/// Builds a synthetic USB Configuration Descriptor containing:
/// - Standard Interface Descriptor for UVC VideoControl (`bInterfaceNumber = 2`, `CC_VIDEO = 0x0e`, `SC_VIDEOCONTROL = 0x01`)
@@ -1,16 +1,16 @@
[package]
name = "insta360-link-server"
name = "open-360-link-server"
version.workspace = true
edition.workspace = true
license.workspace = true
description = "Cross-platform HTTP REST & WebSocket remote control server for Insta360 Link cameras"
description = "Open 360 Link: Cross-platform HTTP REST & WebSocket remote control server for Insta360 Link cameras"
[[bin]]
name = "insta360-link-server"
name = "open-360-link-server"
path = "src/main.rs"
[dependencies]
insta360-link-protocol = { path = "../insta360-link-protocol" }
open-360-link-protocol = { path = "../open-360-link-protocol" }
clap.workspace = true
tokio.workspace = true
axum.workspace = true
@@ -7,7 +7,7 @@ use axum::{
routing::{get, post},
Json, Router,
};
use insta360_link_protocol::{
use open_360_link_protocol::{
list_connected_cameras, AudioCaptureMode, CameraModel, CompositionStyle, DeviceCapabilities,
DeviceInfo, DiscoveredCamera, ExtendFunction, FilterMode, ForbiddenAreaInfo, Gesture,
GestureFunction, HostPtzInfo, Insta360CameraController, MockCameraTransport, NusbTransport,
@@ -1,16 +1,16 @@
use clap::{Parser, ValueEnum};
use insta360_link_protocol::{
use open_360_link_protocol::{
CameraModel, Insta360CameraController, NusbTransport, UvcControlTransport,
};
use insta360_link_server::{build_router, new_mock_state, AppState, ServerTransport};
use open_360_link_server::{build_router, new_mock_state, AppState, ServerTransport};
use std::net::SocketAddr;
use std::sync::{Arc, Mutex};
#[derive(Parser, Debug)]
#[command(
name = "insta360-link-server",
name = "open-360-link-server",
version,
about = "Cross-platform HTTP REST & WebSocket remote control server for Insta360 Link cameras"
about = "Open 360 Link: Cross-platform HTTP REST & WebSocket remote control server for Insta360 Link cameras"
)]
struct Cli {
/// Bind address for HTTP and WebSocket server
@@ -47,7 +47,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
tracing_subscriber::fmt()
.with_env_filter(
tracing_subscriber::EnvFilter::try_from_default_env()
.unwrap_or_else(|_| "insta360_link_server=info,tower_http=info".into()),
.unwrap_or_else(|_| "open_360_link_server=info,tower_http=info".into()),
)
.init();
@@ -1,11 +1,11 @@
use std::collections::HashMap;
use std::net::SocketAddr;
use insta360_link_protocol::{
use open_360_link_protocol::{
AudioCaptureMode, CameraModel, CompositionStyle, ExtendFunction, FilterMode, Gesture,
GestureFunction, TrackSpeed, VideoMode,
};
use insta360_link_server::{
use open_360_link_server::{
build_router, new_mock_state, AudioRequest, CameraStateSnapshot, ImageRequest, ModeRequest,
PresetRequest, PtzRequest, SystemRequest, TrackingRequest,
};