Clip Web videos.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

83 line
1.9 KiB

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