이 글은 Today I Learn 시리즈의 215번째 기록입니다. (총 230개)

시간대에 따라 바뀌는 재생

시각을 지키는 전환과 곡을 안 끊는 전환은 서로 다른 요구다

시간대마다 재생목록이 바뀌게 만들 때, 앞선 TIL 8에서 정한 대로 전환은 곡이 끝나는 자리에서만 하기로 돼 있었다. 곡을 중간에 끊으면 어색하니 그 하나면 될 줄 알았다.

그런데 블록마다 원하는 게 달랐다. 낮 시간대는 곡이 끊기지 않는 게 중요하고, 마감처럼 시각 자체가 의미인 블록은 9시면 9시에 분위기가 바뀌어야 한다. 곡이 5분짜리면 전환이 5분 밀리는데, 손님 있는 시간엔 그게 자연스럽고 마감엔 그게 어긋난다.

하나로 정하면 늘 한쪽이 아쉬운 구조라, 블록마다 고르게 두는 게 맞았다. 설정을 하나 늘리는 비용보다 두 요구를 다 만족시키는 값이 컸다.

여기서 가져갈 건 「옵션을 늘려라」가 아니다. 같은 기능처럼 보이는 요구가 사실 성격이 다른 둘인지를 먼저 확인하라는 것이다. 둘이면 기본값을 정하고 나머지를 예외로 열면 된다.


약관과 계약

강한 조항은 통째로 세우기보다 예외 하나를 막아 두는 편이 안전하다

구독은 완전 무환불로 가기로 했다. 그런데 「어떤 경우에도 환불 없음」을 그대로 두면, 우리 잘못으로 서비스를 못 준 기간까지 덮게 된다. 그 상태면 조항 전체가 불공정하다고 다퉈질 여지가 생긴다. 강하게 쓰려다 조항 자체가 흔들리는 셈이다.

그래서 무환불은 유지하되 「당사 귀책으로 서비스를 제공하지 못한 기간은 그만큼 구독 기간을 연장한다」를 붙였다. 돈을 돌려주는 게 아니라 기간으로 보전하는 거라 현금 흐름은 그대로다.

강한 조항일수록 구멍 하나를 미리 막아 두는 게, 조항 전체를 지키는 방법이다.

라이선스를 장소가 아니라 계정에 건다

처음엔 「계약한 매장 안에서만 재생」으로 적으려 했다. 뜻은 맞는데, 매장을 특정하는 표현이라 가게를 옮기거나 등록 정보를 고칠 때마다 계약을 손대야 한다.

「구독 1건 = 사업장 한 곳, 여러 곳이면 그 수만큼 구독」으로 바꾸니 목적은 그대로 살았다. 체인이 구독 하나로 여러 지점을 돌리는 걸 막는 게 원래 목적이었고, 그건 장소를 특정하지 않아도 표현된다.

막고 싶은 것이 「장소」인지 「동시에 쓰는 수」인지를 먼저 가리면, 계약 문구가 운영을 덜 붙잡는다.

매장에서 트는 것과 영상에 얹는 것은 값이 다르다

금지 목록을 적을 때 재배포·재판매·다운로드·계정 공유까지는 자연스럽게 나왔는데, 「2차 송출」은 빠져 있었다. 우리 음원을 유튜브나 팟캐스트 배경음악으로 얹는 경우다.

매장에서 트는 것과 콘텐츠에 실어 배포하는 것은 도달 범위가 달라 값도 달라야 한다. 같은 「재생」이라는 말에 묶여 있어서 한 덩어리로 보였을 뿐이다. 허용 범위를 적을 때는 「무엇을 하는가」보다 「얼마나 퍼지는가」로 나눠 보는 편이 빠진 걸 찾기 쉽다.

AI가 만든 곡은 재생권까지만 약속할 수 있다

음원은 생성 도구로 만들어 편곡을 얹은 것이다. 도구 약관상 다운로드본은 상업적으로 쓸 수 있지만, 동시에 「저작권이 성립한다고 보장하지 않는다」고 적혀 있다. AI 생성물은 저작권 자체가 안 설 수 있기 때문이다.

그래서 약관에는 「재생할 권리를 제공한다」까지만 적고, 곡의 저작권 귀속이나 독점은 보증하지 않는다는 면책을 넣었다.

재미있는 건 이 약점이 다른 쪽에서는 강점이 된다는 것이다. 저작권 신탁 단체에 맡겨진 곡이 아니라서, 매장이 이 음원을 틀 때 별도 공연사용료를 낼 필요가 없다. 라이브러리를 지키는 힘은 약해지지만, 파는 문구는 오히려 선명해진다. 약점과 강점이 같은 뿌리에서 나올 때는 둘 다 적어 두는 게 정직하고 안전하다.


어디서 파느냐가 값을 가른다

같은 결제사라도 앱 안에서 부르면 수수료가 붙는다

앱을 스토어에 올리기로 하면서, 쓰던 결제사가 무의미해지는 줄 알았다. 확인해 보니 반대였다. 정책이 바뀌어 외부 결제가 허용됐고 수수료도 내려갔다(정기구독 10%). 다만 앱에서 링크를 타고 나가 결제해도 그 수수료와 거래 보고 의무가 따라붙는다. 외부 링크가 공짜라는 뜻이 아니었다.

반면 앱 밖에서 팔면, 즉 웹에서 가입·결제하고 앱은 로그인해서 쓰기만 하면 스토어 결제 규칙에 걸리지 않는다.

그래서 결제사는 그대로 두고 구매 동선만 앱 밖으로 뺐다. 앱에는 누를 수 있는 결제 버튼을 두지 않고 안내 문구만 남겼다.

바뀐 건 「무엇으로 받느냐」가 아니라 「어디서 받느냐」였다. 수수료를 볼 때 결제 수단만 비교하면 절반만 본 것이다.

B2B는 세금계산서가 결제사를 정한다

수수료만 보면 스토어 결제도 나쁘지 않은 수준까지 내려왔다. 그런데 고객이 사업자면 이야기가 달라진다. 매장은 비용 처리를 위해 인보이스가 필요한데, 스토어 결제로는 그게 안 나온다.

판매 대행사 형태의 결제사를 고른 이유가 원래 그거였다는 걸 이 대목에서 다시 확인했다. 개인 대상 앱이면 수수료가 기준이 되지만, 사업자 대상이면 증빙이 먼저다. 고객이 개인인지 사업자인지가 결제 수단 선택을 바꾼다.

플랫폼을 하나 더 늘리는 비용은 코드가 아니라 배포 인프라다

같은 프레임워크로 만들었으니 다른 모바일 플랫폼도 코드는 거의 그대로 나온다. 그래서 「언젠가 같이 올리면 되지」라고 생각하기 쉬운데, 실제 비용은 코드가 아니었다.

연 단위 개발자 등록비가 따로 들고, 빌드와 제출에 특정 운영체제의 기계가 있어야 한다. 지금 쓰는 기계로는 아예 빌드가 안 된다. 심사도 별도고 스토어 등록물도 따로 만들어야 한다.

그래서 한쪽만 먼저 내기로 했다. 매장에 놓을 기기는 어차피 싼 태블릿 하나면 되니 제품 가치가 줄지도 않는다.

「코드가 공유되니 싸다」는 착각을 조심할 것. 플랫폼을 늘리는 비용은 대부분 코드 밖에 있다.


요약

  • 같은 기능처럼 보이는 요구가 성격이 다른 둘이면, 기본값을 정하고 나머지를 예외로 연다.
  • 강한 조항일수록 구멍 하나를 미리 막아 두는 게 조항 전체를 지킨다.
  • 막고 싶은 게 장소인지 동시 사용 수인지 가리면 계약이 운영을 덜 붙잡는다.
  • 허용 범위는 「무엇을 하는가」보다 「얼마나 퍼지는가」로 나눠야 빠진 걸 찾는다.
  • 약점과 강점이 같은 뿌리에서 나오면 둘 다 적어 두는 편이 안전하다.
  • 수수료는 결제 수단이 아니라 판매 위치가 가른다.
  • 고객이 사업자면 수수료보다 증빙이 먼저다.
  • 플랫폼을 늘리는 비용은 코드가 아니라 배포 인프라에 있다.

Series: Today I Learn

1 C++ 자료형(Data Type) 2 MD5 vs pHash 3 C++에서 함수의 선언과 정의 4 Tkinter padx, pady 5 메모리와 포인터 변수 6 Call by Value, Call by Reference, Call by Pointer 비교 7 const 8 Gemfile — Jekyll 프로젝트의 의존성 파일 9 kramdown-parser-gfm — Jekyll의 GFM 파서 10 파서(Parser) 11 AHU vs OHU 12 I might try it vs I'll try it 뉘앙스 차이 13 SESSION_EXPIRE_AT_BROWSER_CLOSE=True 14 configuration key 15 Git stash vs discard 16 subprocess.Popen으로 Windows 탐색기에 명령어를 전달 17 Post 잔디 분석하기 18 Google Sheets Sync 최적화 19 DSL (Domain Specific Language)과 GPL (General Purpose Language) 20 마크다운 표 그리는 방법 21 쿼리 파라미터(Query Parameter). 기존 QR코드 재활용 22 Django 보안 취약점 점검 및 수정 23 OOP Object-Oriented Programming 객체 지향 프로그래밍 24 Fernet 대칭 암호화 25 Jekyll 코드블록 안의 Liquid 태그 26 습관만들기 Pawbit TIL 1 27 insertOnConflictUpdate vs DoUpdate(target) 28 세션 필터 29 아코디언(Accordiaon) UI를 펼친상태로 만들기 30 input의 step 31 습관만들기 Pawbit TIL 2 32 습관만들기 Pawbit TIL 3 33 Word Cloud 34 Google Sheets를 데이터 버스로(with AppSheet) 35 Django 모델 텍스트 필드 자동 수집 패턴 36 localStorage로 섹션 토글 상태 유지 37 순차 ID 생성(`select_for_update()` + `max()` 조합) 38 역참조 검색과 distinct() 39 xlsx 다운로드와 로딩 오버레이 충돌 40 Android 파일 공유 MIME 타입 41 AssetManifest — Flutter 빌드 타임 asset 목록 런타임 조회 42 크레센도 Phaser + TypeScript TIL 1 43 크레센도 Phaser + TypeScript TIL 2 44 크레센도 Phaser + TypeScript TIL 3 45 크레센도 Phaser + TypeScript TIL 4 46 크레센도 Phaser + TypeScript TIL 5 47 여둘까 Office Layout TIL 1 48 습관만들기 Pawbit TIL 4 49 여둘까 Office Layout TIL 2 50 여둘까 Office Layout TIL 3 51 크레센도 Phaser + TypeScript TIL 6 52 UTF-8 BOM과 PowerShell 파일 쓰기 53 소리꽃 KeyBloom TIL 1 54 습관만들기 Pawbit TIL 5 55 여둘까 Office Layout TIL 4 56 소리꽃 KeyBloom TIL 2 57 소리꽃 KeyBloom TIL 3 58 메트로놈 Simple Metronome TIL 1 59 소리꽃 KeyBloom TIL 4 60 메트로놈 Simple Metronome TIL 2 61 소리꽃 KeyBloom TIL 5 62 습관만들기 Pawbit TIL 6 63 크레센도 Phaser + TypeScript TIL 7 64 메트로놈 Simple Metronome TIL 3 65 소설 타임라인 관리 도구 Lumior TIL 1 66 습관만들기 Pawbit TIL 7 67 정적 블로그 SEO 정비와 Pagefind 검색 도입 68 크레센도 Phaser + TypeScript TIL 8 69 메트로놈 Simple Metronome TIL 4 70 습관만들기 Pawbit TIL 8 71 안드로이드 AudioTrack 연속 재생, 실측 피커 정렬, 카메라 토치 플래시 72 메트로놈 Simple Metronome TIL 5 73 모래게임 Sandrop TIL 1 74 습관만들기 Pawbit TIL 9 75 메트로놈 Simple Metronome TIL 6 76 모래게임 Sandrop TIL 2 77 모래게임 Sandrop TIL 3 78 습관만들기 Pawbit TIL 11 79 습관만들기 Pawbit TIL 10 80 메트로놈 Simple Metronome TIL 7 81 모래게임 Sandrop TIL 4 82 모래게임 Sandrop TIL 5 83 습관만들기 Pawbit TIL 12 84 모래게임 Sandrop TIL 6 85 소리꽃 KeyBloom TIL 6 86 모래게임 Sandrop TIL 7 87 모래게임 Sandrop TIL 8 88 소리꽃 KeyBloom TIL 7 89 모래게임 Sandrop TIL 9 90 소리꽃 KeyBloom TIL 8 91 모래게임 Sandrop TIL 10 92 소리꽃 KeyBloom TIL 9 93 콘티온 ContiOn TIL 1 94 소리꽃 KeyBloom TIL 10 95 콘티온 ContiOn TIL 2 96 습관만들기 Pawbit TIL 13 97 콘티온 ContiOn TIL 3 98 룸톤 Roomtone TIL 1 99 모래게임 Sandrop TIL 11 100 소리꽃 KeyBloom TIL 11 101 여둘까 Office Layout TIL 5 102 모래게임 Sandrop TIL 12 103 모래게임 Sandrop TIL 13 104 콘티온 ContiOn TIL 4 105 모래게임 Sandrop TIL 14 106 소리꽃 KeyBloom TIL 12 107 습관만들기 Pawbit TIL 14 108 모래게임 Sandrop TIL 15 109 모래게임 Sandrop TIL 16 110 소리꽃 KeyBloom TIL 13 111 온실 GreenHouse TIL 1 112 콘티온 ContiOn TIL 5 113 모래게임 Sandrop TIL 17 114 소리꽃 KeyBloom TIL 14 115 온실 GreenHouse TIL 2 116 콘티온 ContiOn TIL 6 117 모래게임 Sandrop TIL 18 118 콘티온 ContiOn TIL 7 119 모래게임 Sandrop TIL 19 120 소리꽃 KeyBloom TIL 15 121 룸톤 Roomtone TIL 2 122 모래게임 Sandrop TIL 20 123 모래게임 Sandrop TIL 21 124 소리꽃 KeyBloom TIL 16 125 소리꽃 KeyBloom TIL 17 126 소리꽃 KeyBloom TIL 18 127 여둘까 Office Layout TIL 6 128 소리꽃 KeyBloom TIL 19 129 소리꽃 KeyBloom TIL 20 130 콘티온 ContiOn TIL 8 131 콘티온 ContiOn TIL 9 132 로그스톤 상표 셀프 출원 TIL 1 133 소리꽃 KeyBloom TIL 21 134 로그스톤 샵 LogStone Shop TIL 1 135 소리꽃 KeyBloom TIL 22 136 로그스톤 샵 LogStone Shop TIL 2 137 룸톤 Roomtone TIL 3 138 소리꽃 KeyBloom TIL 23 139 모래게임 Sandrop TIL 22 140 모래게임 Sandrop TIL 23 141 소리꽃 KeyBloom TIL 24 142 로그스톤 샵 LogStone Shop TIL 3 143 모래게임 Sandrop TIL 24 144 소리꽃 KeyBloom TIL 25 145 모래게임 Sandrop TIL 25 146 MiniMacro TIL 1 147 룸톤 Roomtone TIL 4 148 모래게임 Sandrop TIL 26 149 콘티온 ContiOn TIL 10 150 Astro가 무엇인지, 왜 옮기는지 151 룸톤 Roomtone TIL 5 152 룸톤 Roomtone TIL 6 153 모래게임 Sandrop TIL 27 154 소리꽃 KeyBloom TIL 26 155 MiniMacro TIL 2 156 로그스톤 샵 LogStone Shop TIL 4 157 메트로놈 Simple Metronome TIL 8 158 모래게임 Sandrop TIL 28 159 여둘까 Office Layout TIL 7 160 룸톤 Roomtone TIL 7 161 메트로놈 Simple Metronome TIL 9 162 블로그 Astro 이관 TIL 163 여둘까 Office Layout TIL 8 164 로그스톤 샵 LogStone Shop TIL 5 165 모래게임 Sandrop TIL 29 166 오픈데이 Openday TIL 1 167 로그스톤 샵 LogStone Shop TIL 6 168 모래게임 Sandrop TIL 30 169 오픈데이 Openday TIL 2 170 모래게임 Sandrop TIL 31 171 Unreal Engine MCP TIL 1 172 모래게임 Sandrop TIL 32 173 소리꽃 KeyBloom TIL 27 174 콘티온 ContiOn TIL 11 175 오픈데이 Openday TIL 3 176 로그스톤 샵 LogStone Shop TIL 7 177 모래게임 Sandrop TIL 33 178 소리꽃 KeyBloom TIL 28 179 오픈데이 Openday TIL 4 180 여둘까 Office Layout TIL 9 181 오픈데이 Openday TIL 5 182 ScorePlayer TIL 1 183 모래게임 Sandrop TIL 34 184 BuildingHub TIL 1 185 ScorePlayer TIL 2 186 여둘까 Office Layout TIL 10 187 BuildingHub TIL 2 188 ScorePlayer TIL 3 189 Unreal Engine MCP TIL 2 190 궁 미로 PalaceMaze TIL 1 191 메트로놈 Simple Metronome TIL 10 192 메트로놈 Simple Metronome TIL 11 193 오픈데이 Openday TIL 6 194 BuildingHub TIL 3 195 Obsidian vault에서 코드만 빼기 — directory junction 196 ScorePlayer TIL 4 197 여둘까 Office Layout TIL 11 198 오픈데이 Openday TIL 7 199 URL은 바뀔 수 있는 것에 묶지 않는다 200 돌이키기 힘든 변경은 작게 먼저 확인한다 201 도구는 기능이 아니라 내 일에 맞는지로 고른다 202 궁 미로 PalaceMaze TIL 2 203 궁 미로 PalaceMaze TIL 3 204 소리꽃 KeyBloom TIL 29 205 오픈데이 Openday TIL 8 206 룸톤 Roomtone TIL 8 207 BuildingHub TIL 4 208 ScorePlayer TIL 5 209 로그스톤 샵 LogStone Shop TIL 8 210 여둘까 Office Layout TIL 12 211 오픈데이 Openday TIL 9 212 BuildingHub TIL 5 213 MiniMacro TIL 3 214 룸톤 Roomtone TIL 10 215 룸톤 Roomtone TIL 9 읽는 중 216 소리꽃 KeyBloom TIL 30 217 오픈데이 Openday TIL 10 218 여둘까 Office Layout TIL 13 219 룸톤 Roomtone TIL 11 220 소리꽃 KeyBloom TIL 31 221 궁 미로 PalaceMaze TIL 4 222 룸톤 Roomtone TIL 12 223 로그스톤 샵 LogStone Shop TIL 9 224 룸톤 Roomtone TIL 13 225 로그스톤 샵 LogStone Shop TIL 10 226 룸톤 Roomtone TIL 14 227 소리꽃 KeyBloom TIL 32 228 룸톤 Roomtone TIL 15 229 룸톤 Roomtone TIL 16 230 룸톤 Roomtone TIL 17