@matjash/pixi-native-win32-x64 0.2.5 → 0.2.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1210,8 +1210,14 @@ fn ffmpeg_command(
1210
1210
  command.args(["-ss", &options.offset_seconds.to_string()]);
1211
1211
  }
1212
1212
  command.args(&options.input_args);
1213
+ if streaming && options.loop_ {
1214
+ command.args(["-stream_loop", "-1"]);
1215
+ }
1213
1216
  command.args(["-i", &options.source, "-vn"]);
1214
- if let Some(duration) = options.duration_seconds {
1217
+ if let Some(duration) = options
1218
+ .duration_seconds
1219
+ .filter(|_| !(streaming && options.loop_))
1220
+ {
1215
1221
  command.args(["-t", &duration.to_string()]);
1216
1222
  }
1217
1223
  if streaming && (options.playback_rate - 1.0).abs() > f64::EPSILON {
@@ -1342,6 +1348,24 @@ fn redact_credentials(message: &str) -> String {
1342
1348
  mod tests {
1343
1349
  use super::*;
1344
1350
 
1351
+ fn voice_options(looped: bool) -> NativeVoiceOptions {
1352
+ NativeVoiceOptions {
1353
+ owner_id: 1,
1354
+ id: 1,
1355
+ source: "video.mp4".to_string(),
1356
+ ffmpeg_path: "ffmpeg".to_string(),
1357
+ offset_seconds: 0.0,
1358
+ duration_seconds: Some(2.0),
1359
+ volume: 1.0,
1360
+ muted: false,
1361
+ loop_: looped,
1362
+ streaming: true,
1363
+ playback_rate: 1.0,
1364
+ input_args: Vec::new(),
1365
+ output_args: Vec::new(),
1366
+ }
1367
+ }
1368
+
1345
1369
  #[test]
1346
1370
  fn static_voices_share_pcm_with_independent_cursors() {
1347
1371
  let samples = Arc::new(vec![0.1, 0.2, 0.3, 0.4, 0.5, 0.6]);
@@ -1371,6 +1395,20 @@ mod tests {
1371
1395
  assert_eq!(build_atempo_filter(0.25).unwrap(), "atempo=0.5,atempo=0.5");
1372
1396
  }
1373
1397
 
1398
+ #[test]
1399
+ fn streaming_loop_repeats_input_without_a_duration_limit() {
1400
+ let command = ffmpeg_command(&voice_options(true), 48_000, true).unwrap();
1401
+ let args = command
1402
+ .get_args()
1403
+ .map(|arg| arg.to_string_lossy().into_owned())
1404
+ .collect::<Vec<_>>();
1405
+ let loop_index = args.iter().position(|arg| arg == "-stream_loop").unwrap();
1406
+ let input_index = args.iter().position(|arg| arg == "-i").unwrap();
1407
+ assert_eq!(args[loop_index + 1], "-1");
1408
+ assert!(loop_index < input_index);
1409
+ assert!(!args.iter().any(|arg| arg == "-t"));
1410
+ }
1411
+
1374
1412
  #[test]
1375
1413
  fn credentials_are_redacted() {
1376
1414
  assert_eq!(
@@ -10,6 +10,7 @@ export interface DecoderOptions {
10
10
  sourcePaced?: boolean;
11
11
  inputArgs?: string[];
12
12
  outputArgs?: string[];
13
+ loop?: boolean;
13
14
  }
14
15
 
15
16
  export interface VideoFrame {
@@ -33,6 +33,7 @@ pub struct DecoderOptions {
33
33
  pub source_paced: Option<bool>,
34
34
  pub input_args: Option<Vec<String>>,
35
35
  pub output_args: Option<Vec<String>>,
36
+ pub loop_: Option<bool>,
36
37
  }
37
38
 
38
39
  #[napi(object)]
@@ -206,6 +207,7 @@ struct FfmpegRequest {
206
207
  end_time: Option<f64>,
207
208
  input_args: Vec<String>,
208
209
  output_args: Vec<String>,
210
+ looped: bool,
209
211
  }
210
212
 
211
213
  #[napi]
@@ -313,6 +315,7 @@ impl NativeVideoDecoder {
313
315
  end_time: self.options.end_time,
314
316
  input_args: self.options.input_args.clone().unwrap_or_default(),
315
317
  output_args: self.options.output_args.clone().unwrap_or_default(),
318
+ looped: self.options.loop_.unwrap_or(false),
316
319
  };
317
320
  let (spawned, active_backend) = match spawn_ffmpeg(&request, requested_backend) {
318
321
  Ok(spawned) => (spawned, requested_backend),
@@ -696,8 +699,11 @@ fn ffmpeg_args(request: &FfmpegRequest, backend: DecoderBackend) -> Vec<String>
696
699
  args.extend(["-ss".to_string(), request.start_time.to_string()]);
697
700
  }
698
701
  args.extend(request.input_args.iter().cloned());
702
+ if request.looped {
703
+ args.extend(["-stream_loop".to_string(), "-1".to_string()]);
704
+ }
699
705
  args.extend(["-i".to_string(), request.source.clone(), "-an".to_string()]);
700
- if let Some(end_time) = request.end_time {
706
+ if let Some(end_time) = request.end_time.filter(|_| !request.looped) {
701
707
  args.extend([
702
708
  "-t".to_string(),
703
709
  (end_time - request.start_time).to_string(),
@@ -1119,6 +1125,19 @@ mod tests {
1119
1125
  assert!(threads_index > input_index && threads_index < pipe_index);
1120
1126
  }
1121
1127
 
1128
+ #[test]
1129
+ fn loops_full_file_input_without_a_duration_limit() {
1130
+ let mut request = request(30.0, 0.0);
1131
+ request.looped = true;
1132
+ request.end_time = Some(2.0);
1133
+ let args = ffmpeg_args(&request, DecoderBackend::Cpu);
1134
+ let loop_index = args.iter().position(|arg| arg == "-stream_loop").unwrap();
1135
+ let input_index = args.iter().position(|arg| arg == "-i").unwrap();
1136
+ assert_eq!(args[loop_index + 1], "-1");
1137
+ assert!(loop_index < input_index);
1138
+ assert!(!args.iter().any(|arg| arg == "-t"));
1139
+ }
1140
+
1122
1141
  #[test]
1123
1142
  fn builds_serial_software_fallback_filter() {
1124
1143
  let args = ffmpeg_args(&request(30.0, 0.0), DecoderBackend::Cpu);
@@ -1154,6 +1173,7 @@ mod tests {
1154
1173
  source_paced: None,
1155
1174
  input_args: None,
1156
1175
  output_args: None,
1176
+ loop_: None,
1157
1177
  });
1158
1178
  assert!(result.is_err());
1159
1179
  }
@@ -1238,6 +1258,7 @@ mod tests {
1238
1258
  source_paced: None,
1239
1259
  input_args: None,
1240
1260
  output_args: None,
1261
+ loop_: None,
1241
1262
  })
1242
1263
  .unwrap();
1243
1264
  let mut target = vec![0; 6];
@@ -1270,6 +1291,7 @@ mod tests {
1270
1291
  source_paced: None,
1271
1292
  input_args: None,
1272
1293
  output_args: None,
1294
+ loop_: None,
1273
1295
  })
1274
1296
  .unwrap();
1275
1297
  let mut target = vec![0; 5];
@@ -1355,6 +1377,7 @@ mod tests {
1355
1377
  source_paced: None,
1356
1378
  input_args: None,
1357
1379
  output_args: None,
1380
+ loop_: None,
1358
1381
  })
1359
1382
  .unwrap()
1360
1383
  }
@@ -1390,6 +1413,7 @@ mod tests {
1390
1413
  end_time: None,
1391
1414
  input_args: Vec::new(),
1392
1415
  output_args: Vec::new(),
1416
+ looped: false,
1393
1417
  }
1394
1418
  }
1395
1419
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@matjash/pixi-native-win32-x64",
3
- "version": "0.2.5",
3
+ "version": "0.2.7",
4
4
  "type": "commonjs",
5
5
  "description": "Windows x64 native binaries for @matjash/pixi-native",
6
6
  "license": "MIT",