diff --git a/.github/workflows/code_checks.yml b/.github/workflows/core_code_checks.yml similarity index 100% rename from .github/workflows/code_checks.yml rename to .github/workflows/core_code_checks.yml diff --git a/.github/workflows/viewer_build_deploy.yml b/.github/workflows/viewer_build_deploy.yml new file mode 100644 index 000000000..ea89637cf --- /dev/null +++ b/.github/workflows/viewer_build_deploy.yml @@ -0,0 +1,74 @@ +name: Build and deploy Nerfviewer. + +on: + push: + branches: [master] + pull_request: + branches: [master] + +jobs: + build: + name: Build + runs-on: ubuntu-latest + defaults: + run: + working-directory: ./nerfactory/viewer/app + steps: + - name: Checkout code + uses: actions/checkout@master + + - name: Install Node.js + uses: actions/setup-node@v3 + with: + node-version: 17.8.0 + # cache: 'yarn' + + - name: Install packages + run: yarn install + + - name: Build project + run: CI=false yarn build + + - name: Upload production-ready build files + uses: actions/upload-artifact@v2 + with: + name: production-files + path: ./nerfactory/viewer/app/build + + deploy: + name: Deploy + needs: build + runs-on: ubuntu-latest + # if: github.ref == 'refs/heads/master' + + env: + SSH_KEY: ${{secrets.SSH_KEY}} + + steps: + - name: Download artifact + uses: actions/download-artifact@v2 + with: + name: production-files + path: ./nerfactory/viewer/app/build + + - name: Get branch name (merge) + if: github.event_name != 'pull_request' + shell: bash + run: echo "BRANCH_NAME=$(echo ${GITHUB_REF#refs/heads/} | tr / -)" >> $GITHUB_ENV + + - name: Get branch name (pull request) + if: github.event_name == 'pull_request' + shell: bash + run: echo "BRANCH_NAME=$(echo ${GITHUB_HEAD_REF} | tr / -)" >> $GITHUB_ENV + + - run: mkdir ~/.ssh + - run: 'echo "$SSH_KEY" >> ~/.ssh/github_actions_user_key_filename' + - run: chmod 400 ~/.ssh/github_actions_user_key_filename + - run: echo -e "Host github_action_remote_machine\n\tUser eweb0124\n\tHostname 34.102.68.79\n\tIdentityFile ~/.ssh/github_actions_user_key_filename\n\tStrictHostKeyChecking No" >> ~/.ssh/config + - run: ssh github_action_remote_machine 'rm -rf /home/eweb0124/build' + # ${{ env.BRANCH_NAME }} is the branch name + - run: ssh github_action_remote_machine 'mkdir -p /home/eweb0124/viewer/branch/${{ env.BRANCH_NAME }}' + - run: ssh github_action_remote_machine 'rm -rf /home/eweb0124/viewer/branch/${{ env.BRANCH_NAME }}' + - run: scp -r ./nerfactory/viewer/app/build github_action_remote_machine:/home/eweb0124/ + # TODO(ethan): move the current version to an older folder + - run: ssh github_action_remote_machine 'mv /home/eweb0124/build /home/eweb0124/viewer/branch/${{ env.BRANCH_NAME }}' \ No newline at end of file diff --git a/.github/workflows/viewer_client_app.yml b/.github/workflows/viewer_client_app.yml deleted file mode 100644 index 10b889676..000000000 --- a/.github/workflows/viewer_client_app.yml +++ /dev/null @@ -1,57 +0,0 @@ -name: Build and deploy viewer client app. - -on: - push: - branches: [master] - pull_request: - branches: [master] - -jobs: - build: - name: Build - runs-on: ubuntu-latest - defaults: - run: - working-directory: ./nerfactory/viewer/app - steps: - - name: Checkout code - uses: actions/checkout@master - - - name: Install Node.js - uses: actions/setup-node@v3 - with: - node-version: 17.8.0 - - - name: Install packages - run: npm install - - - name: Build project - run: CI=false npm run build - - # - name: Run tests - # run: npm test - - - name: Upload production-ready build files - uses: actions/upload-artifact@v2 - with: - name: production-files - path: ./nerfactory/viewer/app/build - - deploy: - name: Deploy - needs: build - runs-on: ubuntu-latest - if: github.ref == 'refs/heads/master' - - steps: - - name: Download artifact - uses: actions/download-artifact@v2 - with: - name: production-files - path: ./nerfactory/viewer/app/build - - - name: Deploy to gh-pages - uses: peaceiris/actions-gh-pages@v3 - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - publish_dir: ./nerfactory/viewer/app/build \ No newline at end of file diff --git a/.github/workflows/prettier.yaml b/.github/workflows/viewer_prettier.yaml similarity index 92% rename from .github/workflows/prettier.yaml rename to .github/workflows/viewer_prettier.yaml index e812c85f7..0e6771637 100644 --- a/.github/workflows/prettier.yaml +++ b/.github/workflows/viewer_prettier.yaml @@ -1,4 +1,4 @@ -name: Run prettier for viewer client app. +name: Run prettier for Nerfviewer. on: pull_request: diff --git a/docs/tutorials/viewer/viewer_quickstart.md b/docs/tutorials/viewer/viewer_quickstart.md index 686e306f5..c2f63db7c 100644 --- a/docs/tutorials/viewer/viewer_quickstart.md +++ b/docs/tutorials/viewer/viewer_quickstart.md @@ -8,9 +8,8 @@ The viewer is built using [ThreeJS](https://threejs.org/) and packaged into a [R ## Run hosted web viewer -[WOP: This sections is not ready. Please proceed to the "For developers" section.] -1. Open the Client App Viewer at ... `TODO(ethan): host the static website`. +1. Open the Client App Viewer at ... [https://viewer.nerfactory.com/branch/master/?localhost:8051](https://viewer.nerfactory.com/branch/master/?localhost:8051) but make sure to change `localhost:8051` accordingly. 2. Run training script with viewer enabled. Note that you should only use the viewer with a fast pipeline, such as instant ngp. ```shell diff --git a/nerfactory/viewer/app/package.json b/nerfactory/viewer/app/package.json index 03739ef83..8edce16fd 100644 --- a/nerfactory/viewer/app/package.json +++ b/nerfactory/viewer/app/package.json @@ -1,6 +1,6 @@ { "name": "viewer", - "homepage": "https://ethanweber.me/nerfactory-private/", + "homepage": ".", "version": "0.0.0", "private": true, "dependencies": { diff --git a/nerfactory/viewer/app/src/modules/WebRtcWindow/WebRtcWindow.jsx b/nerfactory/viewer/app/src/modules/WebRtcWindow/WebRtcWindow.jsx index 5c009e1f9..ad1401ef1 100644 --- a/nerfactory/viewer/app/src/modules/WebRtcWindow/WebRtcWindow.jsx +++ b/nerfactory/viewer/app/src/modules/WebRtcWindow/WebRtcWindow.jsx @@ -36,15 +36,25 @@ export default function WebRtcWindow() { username: 'openrelayproject', credential: 'openrelayproject', }, + // extra STUN server(s): + // { + // urls: 'stun:stun.l.google.com:19302', + // }, + // extra TURN server(s): + // { + // urls: 'turn:1830walnut.ddns.net', + // username: 'turnuser', + // credential: 'turnpassword', + // }, + // { + // urls: 'turn:turn.nerfactory.com:3478', + // username: 'turnuser', + // credential: 'turnpassword', + // }, ], }); // connect video pc.addEventListener('track', (evt) => { - dispatch({ - type: 'write', - path: 'webrtcState/isConnected', - data: true, - }); if (evt.track.kind === 'video') { [localVideoRef.current.srcObject] = evt.streams; // uses array destructuring } @@ -53,13 +63,16 @@ export default function WebRtcWindow() { // for updating the status of the peer connection pc.oniceconnectionstatechange = () => { - if (pc.iceConnectionState === 'connected') { + // https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/connectionState + console.log(`[webrtc] connectionState: ${ pc.connectionState}`); + if (pc.connectionState === 'connecting' || pc.connectionState === 'connected') { + console.log('[webrtc] connected'); dispatch({ type: 'write', path: 'webrtcState/isConnected', data: true, }); - } else if (pc.iceConnectionState === 'disconnected') { + } else { dispatch({ type: 'write', path: 'webrtcState/isConnected', @@ -75,17 +88,22 @@ export default function WebRtcWindow() { .createOffer() .then((offer) => { console.log('[webrtc] created offer'); + console.log(offer); return pcRef.current.setLocalDescription(offer); }) .then(() => { - console.log('[webrtc] set local description'); // wait for ICE gathering to complete + console.log('[webrtc] set local description'); return new Promise((resolve) => { if (pcRef.current.iceGatheringState === 'complete') { console.log('[webrtc] ICE gathering complete'); resolve(); } else { const checkState = () => { + console.log( + `[webrtc] iceGatheringState: ${ + pcRef.current.iceGatheringState}`, + ); if (pcRef.current.iceGatheringState === 'complete') { pcRef.current.removeEventListener( 'icegatheringstatechange', @@ -94,6 +112,9 @@ export default function WebRtcWindow() { resolve(); } }; + console.log( + '[webrtc] adding listener for `icegatheringstatechange`', + ); pcRef.current.addEventListener( 'icegatheringstatechange', checkState, @@ -125,7 +146,9 @@ export default function WebRtcWindow() { // set the remote description when the offer is received const cmd = msgpack.decode(new Uint8Array(originalCmd.data)); if (cmd.type === 'answer') { + console.log('[webrtc] received answer'); const answer = cmd.data; + console.log(answer); pcRef.current.setRemoteDescription(answer); } }); @@ -133,7 +156,7 @@ export default function WebRtcWindow() { websocket.addEventListener('open', () => { // connect webrtc when the websocket is connected pcRef.current = getRTCPeerConnection(); - console.log('sending offer'); + console.log('[webrtc] starting process'); sendOffer(); }); }, []); // empty dependency array means only run once diff --git a/nerfactory/viewer/server/video_stream.py b/nerfactory/viewer/server/video_stream.py index fb177e7b0..f8ece6057 100644 --- a/nerfactory/viewer/server/video_stream.py +++ b/nerfactory/viewer/server/video_stream.py @@ -79,7 +79,7 @@ class SingleFrameStreamTrack(VideoStreamTrack): def __init__(self): super().__init__() - self.background_frame = np.ones((480, 640, 3), dtype="uint8") * 255 # white background + self.background_frame = np.ones((480, 640, 3), dtype="uint8") * 100 # gray background self.frame = None self.put_frame(self.background_frame) diff --git a/scripts/debugging/run_actions.py b/scripts/debugging/run_actions.py index 9827e1953..83c1a814b 100644 --- a/scripts/debugging/run_actions.py +++ b/scripts/debugging/run_actions.py @@ -22,13 +22,14 @@ def run_command(command: str, continue_on_fail: bool = False) -> None: return ret_code == 0 -def main(continue_on_fail: bool = False): - """Run the github actions locally. +def run_github_actions_file(filename: str, continue_on_fail: bool = False): + """Run a github actions file locally. Args: + filename: Which yml github actions file to run. continue_on_fail: Whether or not to continue running actions commands if the current one fails """ - with open(".github/workflows/code_checks.yml", "rb") as f: + with open(filename, "rb") as f: my_dict = yaml.safe_load(f) steps = my_dict["jobs"]["build"]["steps"] @@ -67,5 +68,17 @@ def main(continue_on_fail: bool = False): print_red("=" * 100) +def run_code_checks(continue_on_fail: bool = False): + """Run a github actions file locally. + + Args: + continue_on_fail: Whether or not to continue running actions commands if the current one fails + """ + # core code checks + run_github_actions_file(filename=".github/workflows/core_code_checks.yml", continue_on_fail=continue_on_fail) + # viewer build and deployment + # run_github_actions_file(filename=".github/workflows/viewer_build_deploy.yml", continue_on_fail=continue_on_fail) + + if __name__ == "__main__": - dcargs.cli(main) + dcargs.cli(run_code_checks)