전체 글 237

안드로이드에서 FFMPEG로 m3u8 to mp4 하기

영상 플랫폼에서 일을 하다보니 m3u8 을 접할 기회가 많아졌다. 사실 우리도 모르게 많은 영상 플랫폼에서 m3u8 을 접하는데 유튜브,아프리카tv, 트위치 등 보통 많은 서비스들이 이를 채택하고 있다. 그 이유는 mp4로 재생할 경우에는 파일을 전부 다운로드 받아야 재생이 가능해서 4분짜리 영상을 앞부분 3초만 볼건데도 다운을 기다려야하고 불필요한 데이터도 낭비하게 한다. 그것을 m3u8 파일은 n초 간격으로 파일을 잘라서 보관하기 때문에 모두 다운받지 않고 필요한 만큼만 다운로드 받아서 볼 수 있게 해준다. 그러나 m3u8 파일을 재생하는 플레이어가 없다면 m3u8 파일은 일반적인 기기에서 실행하기 어렵다. 나같은 경우는 영상의 썸네일을 몇초 간격으로 추출할 필요가 있었는데 m3u8 파일은 특정 라이..

Android 2023.12.02

Android Room Entity Relation

프로젝트를 하다보면 서버를 거칠 필요없이 앱 내부에서만 사용하는 데이터를 관리하고 싶을때가 있다. txt 파일로 앱에 저장하거나 SharedPreferences 를 사용하거나 DataStore 를 사용하거나 여러 방법이 있겠지만 간단하게 저장만을 위한 것이 아닌 많은 데이터들을 좀 더 사용하기 편한 방식으로, 또는 데이터간의 관계를 가지기 위해서는 Room 을 사용해야한다. Sql 에 대한 지식이 있는 사람이라면 간단한 쿼리를 적는건 어렵지 않을 수 있겠지만 나의 경우엔 정말 간단한 쿼리만 적어서 사용했고 1:N 관계나 외래키 등록같은건 Room 에서 다룰일이 없었는데 이번에 사용할 기회가 생겨서 적어보려 한다. Entity(table) 간의 관계 정의하기 room의 관계형 쿼리는 현재 2가지 방식을 통..

Android 2023.12.02

이직 후 근황

영상 플랫폼에서 일한다는건 꽤나 앱개발자로서 흥미롭다. 간단하게 영상 출력해보는 정도로 써본 exoplayer 가 전부였는데 컨버팅, 코덱, ffmpeg , trim , crop , 카메라 등등... 여러가지를 접해보고 있다. 여러 가지 프로젝트를 동시에 하는거보다 하나의 서비스에 몰입해서 애정을 가지고 개발하고 있는 점도 즐거움중에 하나다. 이미 라이브되고 있는 서비스다보니 업데이트 템포를 쫒아가랴 기존의 많은 코드들을 이해하고 익히는데 시간이 좀 걸렸지만 이제는 확실히 적응이 되어가는거 같다. 아직도 공부가 부족해서 헤매는 부분이 있긴하지만 어찌저찌 도움 받으며 해결해나가고 있다. 사이드 프로젝트 이야기를 좀 하자면. 이전에 하던 사이드 프로젝트는 이유는 모르겠지만 어째선가.. 팀원들이 다들 바쁘기도..

잡담 2023.11.16

라이브러리 배포 후 적용을 하려는데 NoClassDefFoundError ?

아마 라이브러리 배포를 처음 해봐서 바보 같은 실수를 한거 같다. aar 로 라이브러리 배포가 됐는데 데모앱에서는 잘됐는데 왜 실제 프로젝트에서는 안되는거야? 하면서 NoClassDefFoundError 를 만났는데 이는 aar 은 라이브러리에 작성된 리소스는 불러오지만 라이브러리에 종속되어있는 다른 라이브러리는 불러오지 않기 때문. 라이브러리 내부에는 적용되어있지만 실 프로젝트에 없는 라이브러리를 적용시켜주었더니 해결. 쓰고보니 뭔가.. 예전에 이런 글을 봤던거 같기도 하네

Android 2023.11.16

첫 퇴사

퇴사를 했다. 2년 반의 첫 회사생활의 마침표를 찍었다. 이런 저런 일도 많았고 많은 사람들을 만나고 또 헤어지길 반복하다가 이제는 내가 떠나가는 날이 왔다. 언젠가 이런 날이 오지 않을까 막연한 생각이였지만 막상하고나니 기분이 너무 좋다거나 후련하다거나 그렇지만은 않은거 같다. 첫 회사이니만큼 애정도 많았고 다니는 동안 이 회사가 잘되길 진심으로 바랬던 것 같다. 불만이 없었던건 아니지만 그만큼 좋은 점도 많았으니 잘 다닐 수 있었다. 사교성이 좋지 않은 나지만 정말 다행히 친근하게 다가와주는 좋은 사람들 덕분에 행복했던 회사 생활이였다. 이젠 내가 그동안 해온 것들이 회사의 자산이 되어 도움이 되어 의미있게 쓰이길 바란다. 많은 사람들이 고생했다는 인사와 앞으로를 응원해주고 격려해줬다. 모두에게 고맙..

잡담 2023.08.30

코루틴에 관한 50가지 질문과 답 - 1

1. Android의 Kotlin 코루틴은 무엇이며 기존 스레딩과 어떻게 다릅니까? 안드로이드에서 Kotlin 코루틴은 스레드와 다릅니다. 코루틴은 사용자 공간에서 구현되며 적은 수의 기본 스레드에 다중화됩니다. 그러므로 스레드를 만들고 파괴하는 오버헤드 없이 매우 가벼운 방식으로 코루틴을 일시 중지하고 다시 시작할 수 있습니다. Kotlin 에서 코루틴은 경량의 비차단 실행 스레드입니다. 즉, 스레드와 달리 코루틴은 사용자 공간에서 구현되며, 매우 가벼운 방식으로 일시 중지하고 다시 시작할 수 있습니다. 이를 통해 오버헤드 없이 많은 수의 코루틴을 실행할 수 있습니다. 2. 코루틴 맥락에서 "suspending functions"의 개념을 설명할 수 있습니까? 코루틴 맥락에서 suspending fun..

Android/Coroutine 2023.07.10

eventFlow 방식으로 이벤트를 처리하고 있을 때 든 생각

보통 sealed class 를 이용해서 각 이벤트마다 따로 묶어서 기능의 성격에 맞게 구분하는데 한 액티비티에 프래그먼트가 3개가 들어있는 화면이 있다고 가정하자 그리고 액티비티의 viewModel 을 모두가 공유하고 있는 상황일때 하나의 event flow 만을 이용해서 처리하면 각 프래그먼트에서 같은 flow 를 콜렉트 하는 상황이 생긴다. 이러면 다른 이벤트를 처리하기전 기존의 flow 를 해제해주지 않으면 한 곳에서 진행중인 collect 가 다른 프래그먼트로 가야할 데이터를 계속 가져가서 원하는 화면에서 원하는대로 동작하지 않는 상황이 생긴다. 그래서 내린 결론은 event flow 는 한 액티비티나 한 프래그먼트에서 즉, View 를 기준으로 같이 쓰이는 애들끼리 묶어서 따로 만들어주는게 관..

Android 2023.07.05

MockK 를 사용해서 테스트 코드를 적어보자

휴일이지만 일 때문에 어쩌다보니 일 아닌 일을 하고 있는데 시간도 많이 남고해서 미뤄놨던 테스트 코드나 적어볼까 하고 뒤적뒤적 하는중 코틀린용 mock 테스트 라이브러리 mockK를 발견하고 테스트 코드를 끄적여봤다. 기존에 자바 진영에서 많이 쓰던 mockito 가 대표적인 mock 라이브러리지만 mockK도 코틀린에 좀 더 적합한 방식을 제공하는것뿐 전체적인 매커니즘은 크게 다르지 않았다. 아 참, 이 글을 읽으러 누추한 블로그까지 찾아오셨다면 mock 에 대해서 알고 있는 분일거라 생각하지만 mock 은 모의객체를 의미한다. 풀어서 말하면 실제로 내부 코드들이 전부 작성되어 작동하는게 아닌 껍데기뿐인 객체라는 말이다. 이런건 왜 필요할까? 귀찮고 불편해서다. 테스트 코드를 작성하다보면 안드로이드의 ..

Android 2023.05.14

Jetpack Compose 에서 Lifecycle 관리하기

컴포즈를 사용하면 기존 Lifecycle 을 이용할때랑 같은 방식으로 작동하지가 않는다. 조금 다른 방식을 사용해야하는데 컴포즈에서 말하는 부수효과에 대한 이해가 필요하다. https://developer.android.com/jetpack/compose/side-effects?hl=ko Compose의 부수 효과 | Jetpack Compose | Android Developers Compose의 부수 효과 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. 부수 효과는 구성 가능한 함수의 범위 밖에서 발생하는 앱 상태에 관한 변경사항입니다. developer.android.com 위 링크에 DisposableEffect 에 대해 예시를 들때 아래 코드와 비슷한 예제가 나온다..

android 12 블루투스 대응

예전에 작성된 코드를 다시 유지보수하는 작업이 필요했다. 이제는 마켓에 앱을 올리려면 targetsdk 가 31 이상이 되도록 강제되는데 이때 버전을 올리면서 블루투스 권한부여에 문제가 생겼고 라는 퍼미션을 추가하여 해결했다. 매니페스트 파일에 위 권한들을 추가해주고 블루투스 권한을 요청하는 시점에서 val permissionList = mutableListOf() for (permission in permissions) { permissionList.add(permission) } ActivityCompat.requestPermissions(context as Activity, permissionList.toTypedArray(), 200) 위 코드처럼 요청해줬다. 코드 일부만 가져와서 적은거라 제대로..

Android 2023.04.06