개발 취재록

선택한 로컬 영상을 다음 페이지에서 다시 골라야 한다면

여러 사람이 각자 준비한 안무 영상을 리더의 조작에 맞춰 재생하는 무용 연습용 웹앱(formation)을 만들고 있었다. 클라우드판을 로컬 개발 서버와 브라우저에서 구현·검증하던 중, 로비에서 영상을 고른 뒤 리더 페이지로 이동하려던 흐름에 제약이 드러났다. 선택한 영상 File을 그 이동 너머로 유지하는 문제 때문에 방 개설 폼의 위치를 바꿨다.

결론

파일을 사용할 리더 페이지로 먼저 이동한 뒤 영상을 고르게 했다. leader.html 안에 개설 모드(create-mode)와 제어 모드(control-mode)를 두고, 파일 선택 → 방 생성 → 재생 제어를 이어 붙였다. 로비에는 방 목록과 새 연습방 만들기 버튼을 남겼다.

변경 전 계획변경 후 흐름
로비 개설 폼에서 영상 선택 → 방 개설 성공 → 리더 페이지로 이동로비에서 리더 페이지로 이동 → 이름·영상 선택 → 방 만들기 → 같은 페이지의 제어 모드

위 흐름은 당시 구현 계획과 변경 보고, 이후 수동 시험 안내에서 확인된다. 수정 전 파일 유실을 재현한 로그는 제시되지 않았으므로, 이 글은 구현 중 발견한 제약에 따른 설계 변경을 다룬다.

상황

목표는 연습할 때마다 노트북 서버를 띄우고 같은 와이파이에서 접속하던 번거로움을 줄이는 것이었다. 영상은 미리 서로 공유하고, 앱은 공개된 접속 경로에서 동기화 신호를 전달하도록 방향을 잡았다. 참가자는 방 목록에서 방을 선택하고 자기 기기의 영상 파일을 골라 리더의 재생 조작을 따라간다.

이번 문제에서 중요한 구성은 세 화면이다. 로비는 방을 찾는 곳, 리더 페이지는 방을 만들고 재생을 조작하는 곳, 뷰어 페이지는 참가자가 자기 영상을 고르고 참여하는 곳으로 정리됐다. 서버 측 신호 전달을 검증한 다음 이 화면들을 연결하는 단계에서 개설 폼의 위치가 바뀌었다.

증상

처음 로비에는 개설 폼과 방 목록이 함께 있었다. 다음 구현 계획도 “방 개설 성공 → 리더 페이지로”였다. 그런데 리더 페이지를 작성하면서 “로비에서 이동하면 영상 File을 유지할 수 없다”는 이유로 개설 기능을 그 안으로 옮겼다. 즉 이 사건의 출발점은 이용자의 파일 유실 신고가 아니라, 파일 선택과 재생을 서로 다른 페이지에 둔 계획의 수정이었다.

원인

당시 구현에서 짚은 제약은 로비에서 선택한 파일을 보유하는 흐름과 리더 페이지에서 그 파일을 재생하는 흐름이 이어지지 않는다는 것이었다. 방 개설 뒤 페이지를 이동하도록 계획했지만, 실제 구현은 파일을 고르는 곳을 리더 페이지로 옮기는 방향으로 바뀌었다.

여기서 얻는 설계상의 해석은 “서버에 방이 생겼다”와 “재생할 화면에 로컬 영상이 준비됐다”를 별도 조건으로 보자는 것이다. 이 사례에서는 두 조건을 같은 리더 페이지 안에서 충족시키는 방법을 택했다. 모든 종류의 화면 전환에서 파일 전달이 불가능하다는 결론이나, 별도 저장·전달 방법을 시험해 배제했다는 결론까지 넓힐 근거는 없다.

해결

로비의 개설 폼을 leader.html로 옮겨 개설 모드와 제어 모드로 구성했다. 이후 시험 안내도 리더 페이지에서 방 이름과 실제 영상을 선택하고, 방을 만든 다음 재생·정지·재생 위치 이동을 조작하는 순서다.

변경 후 검증은 리더 페이지의 실제 처리 경로를 대상으로 했다. 브라우저 안에서 MediaRecorder로 재생 가능한 시험 영상을 만들어 파일 입력에 주입했고, 지문·길이 계산과 방 생성, createObjectURL을 통한 로컬 재생(readyState=4), 동기화 신호 전달이 확인됐다는 보고가 남아 있다. 이는 자동화한 시험 영상의 결과이며 실제 휴대폰 파일 선택 시험을 모두 끝냈다는 뜻은 아니다.

검증 도중 뷰어가 0초에서 멈추기도 했다. 그때도 뷰어의 지문 일치·참여·로컬 영상 준비는 확인된 상태였고, 깨끗하게 다시 로드한 뒤에는 재생 위치가 진행하며 리더를 따라갔다. 따라서 그 관찰을 “로비에서 파일을 잃어버린 현상”의 증거로 가져올 수는 없다.

후속 변경에서는 리더 개설 폼에 선택적인 동선 파일 입력을 추가했고, 배포 후 시험 안내에도 새 연습방 만들기 → 이름·영상 선택 → 방 만들기 → 재생 순서가 유지됐다. 개설 폼을 옮긴 선택은 이 후속 흐름과도 일치한다.

취재 후기 — 방을 만들었다고 영상까지 건너온 건 아니다

정바다
각자 폰에 준비한 안무 영상을 한 명의 조작에 맞춰 보는 앱이잖아. 로비에서 영상을 고르고 방을 만든 다음, 리더 화면으로 보내는 흐름을 잡았어.
정하늘
그런데 리더 화면을 붙이는 단계에서 선택한 File, 그러니까 영상 파일 객체를 페이지 이동 뒤에도 유지하는 문제가 걸렸어. 그래서 개설 위치를 바꾸기로 했지.
박도현
방을 만든 다음 어디로 갈지만 정하면 부족하겠네. 그 화면에서 쓸 영상이 어디서 준비되는지도 같은 흐름에 넣어 판단해야겠어.
정바다
그러면 리더 페이지로 먼저 가서 고르자. create-mode는 방을 만드는 화면, control-mode는 재생을 조작하는 화면으로 두면 되겠네.
정하늘
로비에 있던 개설 폼도 옮겼어. 이제 로비는 방 목록과 새 방 만들기 버튼을 보여주고, 참가자는 참여 링크로 자기 화면에 들어가.
박도은
바꾼 리더 화면은 브라우저에서 시험했어. MediaRecorder, 브라우저의 녹화 기능으로 시험 영상을 만든 뒤 파일 입력에 넣어 실제 처리 경로를 돌렸지.
정하늘
확인할 것은 방 생성만이 아니야. 영상 지문과 길이를 구하고, 고른 영상을 로컬에서 재생하고, 동기화 신호를 보내는 데까지 이어지는지 봐야 해.
박도은
그 경로는 통과했어. createObjectURL, 선택한 파일을 재생에 쓸 주소로 연결하는 호출을 거쳐 로컬 재생이 됐고, 방 생성과 신호 전달도 확인했어.
정하늘
다만 시험 영상으로 확인한 범위야. 실제 영상은 리더 페이지에서 이름과 함께 선택하고 방을 만든 뒤 조작하도록 시험 순서를 따로 남겼어.
박도현
이번 선택에서 배울 것은 파일을 고르는 위치도 화면 설계의 일부라는 거야. 다음 화면에서 할 일을 정할 때, 그 화면이 사용할 파일을 어디서 준비할지도 함께 정해야 해.