Clip Web videos.
No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.

89 líneas
2.0 KiB

  1. import { spawnSync } from 'child_process';
  2. import { convertDurationToSeconds, convertSecondsToDuration } from '../../duration';
  3. const normalizeStartSeconds = (start?: number | string) => {
  4. if (typeof start === 'undefined') {
  5. return 0;
  6. }
  7. if (typeof start === 'string') {
  8. return convertDurationToSeconds(start);
  9. }
  10. return start;
  11. };
  12. const FORMAT_DEFAULT_ARGS = [
  13. '--youtube-skip-dash-manifest',
  14. '-f', 'bestvideo+bestaudio',
  15. ];
  16. const constructDownloadSectionsRegex = (start?: number | string, end?: number | string) => {
  17. const startSeconds = normalizeStartSeconds(start);
  18. if (typeof end !== 'undefined') {
  19. const endSeconds = (
  20. typeof end === 'string'
  21. ? convertDurationToSeconds(end)
  22. : end
  23. );
  24. return `*${convertSecondsToDuration(startSeconds)}-${convertSecondsToDuration(endSeconds)}`;
  25. }
  26. if (startSeconds > 0) {
  27. return `*${convertSecondsToDuration(startSeconds)}-inf`;
  28. }
  29. return null;
  30. };
  31. export const getFileExtension = (downloaderExecutablePath: string, url: string) => {
  32. const result = spawnSync(
  33. downloaderExecutablePath,
  34. [
  35. ...FORMAT_DEFAULT_ARGS,
  36. '--print', 'filename',
  37. '-o', '%(ext)s',
  38. url,
  39. ],
  40. );
  41. if (result.error) {
  42. throw result.error;
  43. }
  44. const errorMessage = result.stderr.toString('utf-8').trim();
  45. if (errorMessage.length > 0) {
  46. throw new Error(errorMessage);
  47. }
  48. return result.stdout.toString('utf-8').trim();
  49. };
  50. export const constructDefaultDownloadArgs = (
  51. outputFilename: string,
  52. url: string,
  53. start?: number | string,
  54. end?: number | string,
  55. ) => {
  56. const defaultDownloadArgs = [
  57. ...FORMAT_DEFAULT_ARGS,
  58. '-o', outputFilename,
  59. ];
  60. const downloadSectionsRegex = constructDownloadSectionsRegex(start, end);
  61. if (typeof downloadSectionsRegex === 'string') {
  62. return [
  63. ...defaultDownloadArgs,
  64. '--force-keyframes-at-cuts',
  65. '--download-sections', downloadSectionsRegex,
  66. url,
  67. ];
  68. }
  69. return [
  70. ...defaultDownloadArgs,
  71. url,
  72. ];
  73. };