ziplayer 0.3.9 → 0.3.11

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.
@@ -905,19 +905,21 @@ export class Player extends EventEmitter {
905
905
  const seekArg = position > 0 ? position : -1;
906
906
 
907
907
  if (filterString || position > 0) {
908
- const processedStream = await this.filter.applyFiltersAndSeek(streamInfo.stream, seekArg);
908
+ const processedStream = await this.filter.applyFiltersAndSeek(streamInfo, seekArg);
909
909
 
910
- // rawStream. Always use Arbitrary so discordjs/voice doesn't re-encode.
911
- const resource = createAudioResource(processedStream, {
910
+ const resource = createAudioResource(processedStream.stream || processedStream.url!, {
912
911
  metadata: track,
913
- inputType: StreamType.Arbitrary,
912
+ inputType:
913
+ processedStream.wasRecreated && !filterString ? StreamType.Arbitrary
914
+ : position > 0 ? StreamType.Raw
915
+ : StreamType.Arbitrary,
914
916
  inlineVolume: true,
915
917
  });
916
918
 
917
- return { resource, processedStream };
919
+ return { resource, processedStream: processedStream.stream! };
918
920
  }
919
921
 
920
- const resource = createAudioResource(streamInfo.stream, {
922
+ const resource = createAudioResource(streamInfo.stream || streamInfo.url!, {
921
923
  metadata: track,
922
924
  inputType:
923
925
  streamInfo.type === "webm/opus" ? StreamType.WebmOpus
@@ -1082,6 +1084,7 @@ export class Player extends EventEmitter {
1082
1084
  const currentResource = this.currentSlot.resource;
1083
1085
  if (!currentResource) return false;
1084
1086
 
1087
+ // Ensure seekOffset is always an integer (milliseconds)
1085
1088
  this.seekOffset = 0;
1086
1089
  const targetVolume = this.getTrackTargetVolume(track);
1087
1090
 
@@ -1959,7 +1962,7 @@ export class Player extends EventEmitter {
1959
1962
  }
1960
1963
 
1961
1964
  // Apply filters if any are active
1962
- let finalStream = streamInfo.stream;
1965
+ let finalStream = streamInfo;
1963
1966
 
1964
1967
  if (saveOptions.filter || saveOptions.seek) {
1965
1968
  try {
@@ -1970,14 +1973,14 @@ export class Player extends EventEmitter {
1970
1973
  }
1971
1974
 
1972
1975
  this.debug(`[Player] Applying filters to save stream: ${this.filter.getFilterString() || "none"}`);
1973
- finalStream = await this.filter.applyFiltersAndSeek(streamInfo.stream, saveOptions.seek || 0).catch((err) => {
1976
+ finalStream = await this.filter.applyFiltersAndSeek(streamInfo, saveOptions.seek || 0).catch((err) => {
1974
1977
  this.debug(`[Player] Error applying filters to save stream:`, err);
1975
- return streamInfo!.stream; // Fallback to original stream
1978
+ return streamInfo; // Fallback to original stream
1976
1979
  });
1977
1980
  }
1978
1981
 
1979
1982
  // Return the stream directly - caller can pipe it to fs.createWriteStream()
1980
- return finalStream;
1983
+ return finalStream.stream!;
1981
1984
  } catch (error) {
1982
1985
  this.debug(`[Player] save error:`, error);
1983
1986
  this.emit("playerError", error as Error, track);
@@ -2278,27 +2281,36 @@ export class Player extends EventEmitter {
2278
2281
  * @returns Formatted time string with leading zeros
2279
2282
  */
2280
2283
  formatTime(ms: number): string {
2281
- const totalSeconds = Math.floor(ms / 1000);
2282
- const hours = Math.floor(totalSeconds / 3600);
2283
- const minutes = Math.floor((totalSeconds % 3600) / 60);
2284
- const seconds = totalSeconds % 60;
2284
+ // Ensure ms is an integer and convert to seconds
2285
+ const totalSeconds = Math.floor(ms / 1000) | 0;
2286
+ const hours = Math.floor(totalSeconds / 3600) | 0;
2287
+ const minutes = Math.floor((totalSeconds % 3600) / 60) | 0;
2288
+ const seconds = (totalSeconds % 60) | 0;
2289
+
2285
2290
  const parts: string[] = [];
2286
- if (hours > 0) parts.push(String(hours).padStart(2, "0"));
2287
- parts.push(String(minutes).padStart(2, "0"));
2291
+
2292
+ if (hours > 0) {
2293
+ parts.push(String(hours)); // Giờ không padStart (ví dụ: 1:05:00)
2294
+ parts.push(String(minutes).padStart(2, "0"));
2295
+ } else {
2296
+ parts.push(String(minutes)); // Phút không padStart nếu là số đầu tiên (ví dụ: 0:30 thay vì 00:30)
2297
+ }
2298
+
2288
2299
  parts.push(String(seconds).padStart(2, "0"));
2289
2300
  return parts.join(":");
2290
2301
  }
2291
2302
 
2292
2303
  /**
2293
2304
  * Format time without leading zeros for hours (1:22:12 or 3:45)
2294
- * @param ms - Time in milliseconds
2305
+ * @param ms - Time in milliseconds (must be integer)
2295
2306
  * @returns Compact formatted time string
2296
2307
  */
2297
2308
  formatTimeCompact(ms: number): string {
2298
- const totalSeconds = Math.floor(ms / 1000);
2299
- const hours = Math.floor(totalSeconds / 3600);
2300
- const minutes = Math.floor((totalSeconds % 3600) / 60);
2301
- const seconds = totalSeconds % 60;
2309
+ // Ensure ms is an integer and convert to seconds
2310
+ const totalSeconds = Math.floor(ms / 1000) | 0;
2311
+ const hours = Math.floor(totalSeconds / 3600) | 0;
2312
+ const minutes = Math.floor((totalSeconds % 3600) / 60) | 0;
2313
+ const seconds = (totalSeconds % 60) | 0;
2302
2314
 
2303
2315
  if (hours > 0) {
2304
2316
  return `${hours}:${String(minutes).padStart(2, "0")}:${String(seconds).padStart(2, "0")}`;
@@ -2341,8 +2353,9 @@ export class Player extends EventEmitter {
2341
2353
  };
2342
2354
  }
2343
2355
 
2344
- const total = track.duration > 1000 ? track.duration : track.duration * 1000;
2345
- const current = resource.playbackDuration + this.seekOffset;
2356
+ // Ensure all time values are integers (milliseconds)
2357
+ const total = Math.floor(track.duration > 1000 ? track.duration : track.duration * 1000) | 0;
2358
+ const current = Math.floor(resource.playbackDuration + this.seekOffset) | 0;
2346
2359
 
2347
2360
  return {
2348
2361
  current: current,
@@ -2471,20 +2484,22 @@ export class Player extends EventEmitter {
2471
2484
  const track = this.queue.currentTrack;
2472
2485
  this.debug(`[Player] Refreshing player resource for track: ${track.title}`);
2473
2486
 
2474
- const currentPosition = position >= 0 ? position : (this.currentResource?.playbackDuration ?? 0);
2475
- this.seekOffset = currentPosition;
2487
+ // Ensure all time values are integers (milliseconds)
2488
+ const currentPosition = (position >= 0 ? position : (this.currentResource?.playbackDuration ?? 0) + this.seekOffset) | 0;
2489
+
2490
+ this.seekOffset = currentPosition | 0;
2476
2491
  const wasPaused = this.isPaused;
2477
- const playbackDuration = this.currentResource?.playbackDuration ?? 0;
2492
+ const playbackDuration = (this.currentResource?.playbackDuration ?? 0) | 0;
2478
2493
 
2479
2494
  const isForwardSeek = position < 0 || position >= playbackDuration;
2480
2495
  const currentStreamId = this.currentSlot.streamId;
2481
2496
 
2482
- // Try to grab the raw source stream for reuse (forward seeks only)
2497
+ // Try to grab the raw source stream for reuse (only when not seeking, i.e. just applying filters)
2483
2498
  let reuseStream: import("stream").Readable | null = null;
2484
- if (isForwardSeek && currentStreamId) {
2499
+ if (position < 0 && isForwardSeek && currentStreamId) {
2485
2500
  reuseStream = this.streamManager.getRawStream(currentStreamId);
2486
2501
  if (reuseStream) {
2487
- this.debug(`[Player] Will reuse source stream for seek (pos: ${currentPosition}ms)`);
2502
+ this.debug(`[Player] Will reuse source stream for filter application`);
2488
2503
  }
2489
2504
  }
2490
2505