snobu / destreamer

Save Microsoft Stream videos for offline enjoyment.
MIT License
2.36k stars 442 forks source link

Support for Apple Silicon (M1) #355

Closed bmaeck closed 3 years ago

bmaeck commented 3 years ago

Hi, I wanted to run destreamer on a M1 Mac. It is complaining that Chromium is not available for ARM64. I was installing Chromium using brew, but error is still persistent.

npm ERR! code 1
npm ERR! path /Users/username/work/destreamer/node_modules/puppeteer
npm ERR! command failed
npm ERR! command sh -c node install.js
npm ERR! The chromium binary is not available for arm64:
npm ERR! If you are on Ubuntu, you can install with:
npm ERR!
npm ERR!  apt-get install chromium-browser
npm ERR!
npm ERR! /Users/username/work/destreamer/node_modules/puppeteer/lib/cjs/puppeteer/node/BrowserFetcher.js:112
npm ERR!             throw new Error();
npm ERR!             ^
npm ERR!
npm ERR! Error
npm ERR!     at /Users/username/work/destreamer/node_modules/puppeteer/lib/cjs/puppeteer/node/BrowserFetcher.js:112:19
npm ERR!     at FSReqCallback.oncomplete (node:fs:193:21)

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/username/.npm/_logs/2021-03-30T06_39_40_614Z-debug.log
snobu commented 3 years ago

Plug in your own browser. See this - https://github.com/snobu/destreamer/issues/357#issuecomment-811085553

Any DevTools-speaking browser (that includes any Chromium-based browser) should work with puppeteer. I believe Safari isn't one so ditch that from the start.

If there isn't already one for M1 Macs, you can build it yourself - https://chromium.googlesource.com/chromium/src/+/master/docs/mac_arm64.md

Microsoft Edge (https://www.microsoft.com/en-us/edge/features) has an M1 build, also Google claims to have Chrome for M1 here: https://google.com/chrome/

Everything else in destreamer should run just fine on ARM64 since... well it's all JavaScript anyway. I'm sure there's an ARM64 ffmpeg build since i remember running it on a Raspberry Pi.

bmaeck commented 3 years ago

I was changing the value already to: executablePath: '/Applications/Chromium.app',. When I am running npm install, I receive the message above. When I am running npm run build, I am getting following message:

> destreamer@2.1.0 build
> echo Transpiling TypeScript to JavaScript... && node node_modules/typescript/bin/tsc && echo Destreamer was built successfully.

Transpiling TypeScript to JavaScript...
node:internal/modules/cjs/loader:927
  throw err;
  ^

Error: Cannot find module '/Users/username/work/destreamer/node_modules/typescript/bin/tsc'
    at Function.Module._resolveFilename (node:internal/modules/cjs/loader:924:15)
    at Function.Module._load (node:internal/modules/cjs/loader:769:27)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:76:12)
    at node:internal/main/run_main_module:17:47 {
  code: 'MODULE_NOT_FOUND',
  requireStack: []
}
npm ERR! code 1
npm ERR! path /Users/username/work/destreamer
npm ERR! command failed
npm ERR! command sh -c echo Transpiling TypeScript to JavaScript... && node node_modules/typescript/bin/tsc && echo Destreamer was built successfully.

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/uername/.npm/_logs/2021-03-31T15_40_03_989Z-debug.log
snobu commented 3 years ago

Try removing puppeteer from dependencies in package.json and run npm install again. I really hope there is a TypeScript compiler for ARM64 and the error you're getting is from puppeteer breaking npm install (which should be fixed by removing it from dependencies).

lukaarma commented 3 years ago

you can't remove puppeteer completely @snobu (and tsc its a .js file executed via node so no worries there) run npm uninstall puppeteer; npm i puppeteer-core to replace puppeteer with a browserless version, then run npm i; npm run build and if you plugged in your browser it should work.

Before running any of the above I suggest starting from a fresh clone, so remove the folder you have and pull down again the repo.

snobu commented 3 years ago

Yes, what @lukaarma said. :) Those are the good instructions actually.

bmaeck commented 3 years ago

Thanks for your feedback. The solution proposed from @lukaarma was working so far and I was able to build destreamer. Now I am facing the next issue:

./destreamer.sh -i https://web.microsoftstream.com/video/d3e50eb1-<some-uid>

Created directory: videos
node:internal/modules/cjs/loader:927
  throw err;
  ^

Error: Cannot find module 'puppeteer'
Require stack:
- /Users/username/work/destreamer/build/src/PuppeteerHelper.js
- /Users/username/work/destreamer/build/src/TokenCache.js
- /Users/username/work/destreamer/build/src/destreamer.js
    at Function.Module._resolveFilename (node:internal/modules/cjs/loader:924:15)
    at Function.Module._load (node:internal/modules/cjs/loader:769:27)
    at Module.require (node:internal/modules/cjs/loader:996:19)
    at require (node:internal/modules/cjs/helpers:92:18)
    at Object.<anonymous> (/Users/username/work/destreamer/build/src/PuppeteerHelper.js:8:37)
    at Module._compile (node:internal/modules/cjs/loader:1092:14)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1121:10)
    at Module.load (node:internal/modules/cjs/loader:972:32)
    at Function.Module._load (node:internal/modules/cjs/loader:813:14)
    at Module.require (node:internal/modules/cjs/loader:996:19) {
  code: 'MODULE_NOT_FOUND',
  requireStack: [
    '/Users/username/work/destreamer/build/src/PuppeteerHelper.js',
    '/Users/username/work/destreamer/build/src/TokenCache.js',
    '/Users/username/work/destreamer/build/src/destreamer.js'
  ]
}
snobu commented 3 years ago

I think you need to replace the puppeteer import at the top of destreamer.ts with puppeteer-core but wait for @lukaarma to confirm first.

lukaarma commented 3 years ago

yes i guess you are right... you have to change these lines https://github.com/snobu/destreamer/blob/eb588f74a3e172659460743c76d15e2e64032f47/src/destreamer.ts#L15 https://github.com/snobu/destreamer/blob/eb588f74a3e172659460743c76d15e2e64032f47/src/PuppeteerHelper.ts#L2 https://github.com/snobu/destreamer/blob/eb588f74a3e172659460743c76d15e2e64032f47/src/TokenCache.ts#L9 to import puppeteer from 'puppeteer-core'


That should solve it (I think) @bmaeck

bmaeck commented 3 years ago

Thank you @lukaarma it is now looking good :)

lukaarma commented 3 years ago

I'm closing this @bmaeck, let me know if you need more help

Michael-Z-Freeman commented 1 year ago

Hi. I did all the above and get ...

michaelzfreeman@Michaels-MacBook-Air.local
~/UseTheSourceLuke/destreamer
$ npm i; npm run build

up to date, audited 414 packages in 571ms

47 packages are looking for funding
  run `npm fund` for details

10 vulnerabilities (1 moderate, 6 high, 3 critical)

To address issues that do not require attention, run:
  npm audit fix

To address all issues (including breaking changes), run:
  npm audit fix --force

Run `npm audit` for details.

> destreamer@2.1.0 build
> echo Transpiling TypeScript to JavaScript... && node node_modules/typescript/bin/tsc && echo Destreamer was built successfully.

Transpiling TypeScript to JavaScript...
node_modules/puppeteer-core/lib/types.d.ts:1433:22 - error TS2589: Type instantiation is excessively deep and possibly infinite.

1433 export declare class ElementHandle<ElementType extends Node = Element> extends JSHandle<ElementType> {
                          ~~~~~~~~~~~~~

node_modules/puppeteer-core/lib/types.d.ts:1482:146 - error TS2304: Cannot find name 'Awaited'.

1482     ]> = EvaluateFunc<[ElementHandle<NodeFor<Selector>>, ...Params]>>(selector: Selector, pageFunction: Func | string, ...args: Params): Promise<Awaited<ReturnType<Func>>>;
                                                                                                                                                      ~~~~~~~

node_modules/puppeteer-core/lib/types.d.ts:1519:149 - error TS2304: Cannot find name 'Awaited'.

1519     ]> = EvaluateFunc<[HandleFor<Array<NodeFor<Selector>>>, ...Params]>>(selector: Selector, pageFunction: Func | string, ...args: Params): Promise<Awaited<ReturnType<Func>>>;
                                                                                                                                                         ~~~~~~~

node_modules/puppeteer-core/lib/types.d.ts:2191:169 - error TS2304: Cannot find name 'Awaited'.

2191     evaluateHandle<Params extends unknown[], Func extends EvaluateFunc<Params> = EvaluateFunc<Params>>(pageFunction: Func | string, ...args: Params): Promise<HandleFor<Awaited<ReturnType<Func>>>>;
                                                                                                                                                                             ~~~~~~~

node_modules/puppeteer-core/lib/types.d.ts:2198:153 - error TS2304: Cannot find name 'Awaited'.

2198     evaluate<Params extends unknown[], Func extends EvaluateFunc<Params> = EvaluateFunc<Params>>(pageFunction: Func | string, ...args: Params): Promise<Awaited<ReturnType<Func>>>;
                                                                                                                                                             ~~~~~~~

node_modules/puppeteer-core/lib/types.d.ts:2238:146 - error TS2304: Cannot find name 'Awaited'.

2238     ]> = EvaluateFunc<[ElementHandle<NodeFor<Selector>>, ...Params]>>(selector: Selector, pageFunction: Func | string, ...args: Params): Promise<Awaited<ReturnType<Func>>>;
                                                                                                                                                      ~~~~~~~

node_modules/puppeteer-core/lib/types.d.ts:2262:138 - error TS2304: Cannot find name 'Awaited'.

2262     ]> = EvaluateFunc<[Array<NodeFor<Selector>>, ...Params]>>(selector: Selector, pageFunction: Func | string, ...args: Params): Promise<Awaited<ReturnType<Func>>>;
                                                                                                                                              ~~~~~~~

node_modules/puppeteer-core/lib/types.d.ts:2366:209 - error TS2304: Cannot find name 'Awaited'.

2366     waitForFunction<Params extends unknown[], Func extends EvaluateFunc<Params> = EvaluateFunc<Params>>(pageFunction: Func | string, options?: FrameWaitForFunctionOptions, ...args: Params): Promise<HandleFor<Awaited<ReturnType<Func>>>>;
                                                                                                                                                                                                                     ~~~~~~~

node_modules/puppeteer-core/lib/types.d.ts:3179:68 - error TS2304: Cannot find name 'Awaited'.

3179         ]>>(pageFunction: Func | string, ...args: Params): Promise<Awaited<ReturnType<Func>>>;
                                                                        ~~~~~~~

node_modules/puppeteer-core/lib/types.d.ts:3188:78 - error TS2304: Cannot find name 'Awaited'.

3188         ]>>(pageFunction: Func | string, ...args: Params): Promise<HandleFor<Awaited<ReturnType<Func>>>>;
                                                                                  ~~~~~~~

node_modules/puppeteer-core/lib/types.d.ts:4131:173 - error TS2304: Cannot find name 'Awaited'.

4131         evaluateHandle<Params extends unknown[], Func extends EvaluateFunc<Params> = EvaluateFunc<Params>>(pageFunction: Func | string, ...args: Params): Promise<HandleFor<Awaited<ReturnType<Func>>>>;
                                                                                                                                                                                 ~~~~~~~

node_modules/puppeteer-core/lib/types.d.ts:4221:150 - error TS2304: Cannot find name 'Awaited'.

4221         ]> = EvaluateFunc<[ElementHandle<NodeFor<Selector>>, ...Params]>>(selector: Selector, pageFunction: Func | string, ...args: Params): Promise<Awaited<ReturnType<Func>>>;
                                                                                                                                                          ~~~~~~~

node_modules/puppeteer-core/lib/types.d.ts:4287:142 - error TS2304: Cannot find name 'Awaited'.

4287         ]> = EvaluateFunc<[Array<NodeFor<Selector>>, ...Params]>>(selector: Selector, pageFunction: Func | string, ...args: Params): Promise<Awaited<ReturnType<Func>>>;
                                                                                                                                                  ~~~~~~~

node_modules/puppeteer-core/lib/types.d.ts:5077:157 - error TS2304: Cannot find name 'Awaited'.

5077         evaluate<Params extends unknown[], Func extends EvaluateFunc<Params> = EvaluateFunc<Params>>(pageFunction: Func | string, ...args: Params): Promise<Awaited<ReturnType<Func>>>;
                                                                                                                                                                 ~~~~~~~

node_modules/puppeteer-core/lib/types.d.ts:5513:213 - error TS2304: Cannot find name 'Awaited'.

5513         waitForFunction<Params extends unknown[], Func extends EvaluateFunc<Params> = EvaluateFunc<Params>>(pageFunction: Func | string, options?: FrameWaitForFunctionOptions, ...args: Params): Promise<HandleFor<Awaited<ReturnType<Func>>>>;
                                                                                                                                                                                                                         ~~~~~~~

node_modules/puppeteer-core/lib/types.d.ts:6845:162 - error TS2304: Cannot find name 'Awaited'.

6845              evaluate<Params extends unknown[], Func extends EvaluateFunc<Params> = EvaluateFunc<Params>>(pageFunction: Func | string, ...args: Params): Promise<Awaited<ReturnType<Func>>>;
                                                                                                                                                                      ~~~~~~~

node_modules/puppeteer-core/lib/types.d.ts:6858:178 - error TS2304: Cannot find name 'Awaited'.

6858              evaluateHandle<Params extends unknown[], Func extends EvaluateFunc<Params> = EvaluateFunc<Params>>(pageFunction: Func | string, ...args: Params): Promise<HandleFor<Awaited<ReturnType<Func>>>>;
                                                                                                                                                                                      ~~~~~~~

src/destreamer.ts:51:20 - error TS2503: Cannot find namespace 'puppeteer'.

51     const browser: puppeteer.Browser = await puppeteer.launch({
                      ~~~~~~~~~

src/destreamer.ts:61:17 - error TS2503: Cannot find namespace 'puppeteer'.

61     const page: puppeteer.Page = (await browser.pages())[0];
                   ~~~~~~~~~

src/destreamer.ts:84:42 - error TS2503: Cannot find namespace 'puppeteer'.

84     await browser.waitForTarget((target: puppeteer.Target) => target.url().endsWith('microsoftstream.com/'), { timeout: 150000 });
                                            ~~~~~~~~~

src/TokenCache.ts:60:20 - error TS2503: Cannot find namespace 'puppeteer'.

60     const browser: puppeteer.Browser = await puppeteer.launch({
                      ~~~~~~~~~

src/TokenCache.ts:71:17 - error TS2503: Cannot find namespace 'puppeteer'.

71     const page: puppeteer.Page = (await browser.pages())[0];
                   ~~~~~~~~~

src/TokenCache.ts:74:42 - error TS2503: Cannot find namespace 'puppeteer'.

74     await browser.waitForTarget((target: puppeteer.Target) => target.url().includes(videoId), { timeout: 30000 });
                                            ~~~~~~~~~

Found 23 errors.
JaxkDev commented 7 months ago

yeah same here :(

AntonioDiSalvo commented 6 months ago

is anyone running on ARM Macs successfully in the end? Im stuck like the last two comments outline. Any help appreciated :)

Michael-Z-Freeman commented 6 months ago

is anyone running on ARM Macs successfully in the end? Im stuck like the last two comments outline. Any help appreciated :)

Not worth it IMO. Way too many hoops to jump through. Install it on a Linux machine, real or virtual.