728x90

www.bookjournalism.com/news/23144

 

녹색 백조를 막기 위한 약속 — 북저널리즘 - 젊은 혁신가를 위한 콘텐츠 커뮤니티

조 바이든 미국 대통령 당선인이 파리 기후 협약 재가입 을 1호 공약으로 내걸었다. 미국은 지난 4일 공식 탈퇴했다. 파리 협약은 지구 평균 온도가 산업 혁명 이전보다 2도 이상 상승하지 않도록

www.bookjournalism.com

 빨리 가는데에는 수단 방법을 가릴 필요 없을 지도 모르지만, 오래 가기 위해서는 모든 이들과 적절한 공조, 협력이 필요하다. 조 바이든의 당선으로 미국이 환경 보전을 위한 공조로 방향을 선회한 점이 다행이라고 생각한다.
 환경 파괴로 인한 경제 피해라는 뜻의 '그린 스완'은 이미 우리에게 가시화된 현상일지도 모른다. 우한 시장에서 각종 동물의 균이 얽히고 섥혀 만들어진 코로나 19도 어쩌면 그러한 예시 중 하나일 지 모른다. '자연스러운' 자연을 억지로 비튼 결과는 결국 우리에게 돌아오게 될 것이다.


www.bookjournalism.com/news/23156

 

우리 사장님이 AI? — 북저널리즘 - 젊은 혁신가를 위한 콘텐츠 커뮤니티

배달 노동자들이 모인 라이더유니온이 지난 3일 기자 회견을 열었다. 이들은 배달 앱에 적용된 인공지능(AI)의 알고리즘으로 입은 피해를 호소하면서 배달원에게 알고리즘에 대응할 수 있는 권

www.bookjournalism.com

AI를 이용한 배차 방식은 자율적으로 운행하는 라이더들과 상반되어 운영되는, 오로지 배달 플랫폼의 배차 효율을 중시하는 방식일 것이다. 어떻게 보면 효율적일지 모르지만, 배달 노동자들의 경우 일종의 자영업 형태로 운영되는 것으로 아는데 그렇다면 그들이 배차 방식을 선택할 권리 역시 부여되어야 할 필요가 있다고 생각한다. 
 직선 거리 기준의 배차는 배달 플랫폼이 하루빨리 해결해야 할 문제라고 생각한다. 최근 지도 서비스를 보면 골목이 아닌 지도상의 임의 지점까지도 도달 경로를 잡아낼 정도로 발달한 상태인데, 지형 지물마저 무시한 배치는 분명 개발 부문의 잘못이 없지 않을 것이다.

728x90
728x90

www.bookjournalism.com/news/23027

 

나의 아이스팩은 지구의 핫팩 — 북저널리즘 - 젊은 혁신가를 위한 콘텐츠 커뮤니티

코로나19로 온라인 식품 주문이 늘면서 올해 아이스팩 사용량이 지난해보다 1억 개 늘어난 3억 2000만 개에 달할 전망이다. 커머스 기업부터 정부, 지방 자치 단체에 이르기까지 아이스팩 처리에

www.bookjournalism.com

언택트 시대가 되면서 배달 총량이 어마어마하게 늘어남에 따라 쓰레기 처리 문제가 더욱 대두되는 것 같다. 배달서비스가 발달하면서 신선식품의 간편한 배달이 가능하게 되었지만, 문제는 그 과정에 쓰이는 아이스팩 역시 '아이스' 가 아니라는 점에 있다. 얼음팩에 비해 안정적이라는 장점이 있다 해도, 환경 진화적 대체재가 하루빨리 나왔으면 한다.


www.bookjournalism.com/news/23040

 

편한 것이 힙하다 — 북저널리즘 - 젊은 혁신가를 위한 콘텐츠 커뮤니티

판데믹 시대의 힙 한 패션은 무엇일까. 물놀이할 때 신는 신발, 전문직 종사자들의 실내화로 여겨졌던 샌들 크록스 의 인기가 높아지고 있다. 올해 미국 내 신발 판매는 20퍼센트 감소했지만, 크

www.bookjournalism.com

 지금까지의 많은 패션 유행은 주로 나를 표현하는 데에 그 목적을 두고 있었다. 패션을 사랑하는 이들은 약간의 편의를 희생하면서 더 단정하거나 혹은 더 화려한 멋을 뽐낼 다양한 수단을 찾곤 했다고 볼 수 있을 것이다.
 하지만 언택트로 인해 세상과 사람이 단절되기 시작하면서, 이러한 패션도 나를 세상에 표현하기보다는 나를 위하는 쪽으로 변화하는 것 같다. 타인과의 만남의 빈도가 줄어들면서 다른 의미로 자신에게 더 신경을 쓰게 되었고, 이로 인해 크록스와 같은 몸에 편한 옷들이 인기를 끌게 된 것으로 보인다.

728x90
728x90

www.bookjournalism.com/news/22945

 

우편 투표가 승부를 가른다 — 북저널리즘 - 젊은 혁신가를 위한 콘텐츠 커뮤니티

미국 대선이 혼전으로 치닫고 있다. 도널드 트럼프 미국 대통령이 최대 격전지인 플로리다에서 승리하며 예상 밖 선전을 펼치고 있기 때문이다. 두 후보는 5일 새벽 1시 현재 개표가 완료되지 않

www.bookjournalism.com

역대 대선 중 가장 혼란스러운 선거가 아닌가 싶다. 여러 논란이 얽히면서 둘 중 누가 될지 잘 가늠이 안됐었는데 결국 바이든 후보로 결과가 나는가 싶더니 개표 중지라... 사실 두 후보 중 누가 되더라도 이번 임기의 미국의 행보는 여전히 우려스러운 면이 있을 듯하다.


www.bookjournalism.com/news/22925

 

캐럴 연금 나눠 받는 음악 펀드 — 북저널리즘 - 젊은 혁신가를 위한 콘텐츠 커뮤니티

히트곡의 주주 가 늘고 있다. 2일 음악 IP 투자 회사 힙노시스 송 펀드 가 3만 3000곡의 저작권을 샀다. 캐럴 연금 으로 유명한 머라이어 캐리의 All I Want For Christmas Is You 등 다양한 히트곡이 포함됐

www.bookjournalism.com

컨텐츠 사업은 분야를 막론하고 높은 부가가치를 갖는 사업이라고 볼 수 있다. 그 중에서도 장소, 시간과 독립적으로, 또 연속해서 소비되는 경향이 있는 음악 저작권은 수익이나 안정성 면으로나 매우 매력적인 상품으로 보인다. 다만 음악 펀드는 지분을 나눠갖는 구조인 만큼 중간에 저작권 분쟁 시의 처리 과정이 굉장히 복잡해지지는 않을지 궁금증이 생긴다.

728x90
728x90

www.bookjournalism.com/news/22831

 

아끼는 마음과 기술이 만나면 — 북저널리즘 - 젊은 혁신가를 위한 콘텐츠 커뮤니티

미국의 온라인 서점 북샵(Bookshop.org)이 지난 2일 영국에 진출했다. 북샵은 온라인 도서 판매 수익의 일부를 독립 서점에 지급하는 스타트업이다. 아직 작지만 아마존의 건강한 대안으로 주목받고

www.bookjournalism.com

도서정가제로 오히려 동네 서점들이 판매 경쟁력을 잃는 피해를 입었지만, 그와 반대로 일정한 분야에 특화된 서점들이 나타나기 시작했다는 점은 그나마 긍정적인 변화로 보인다. 이는 가격보다 책들의 가치를 살릴 수 있는 방향으로 서점의 변화가 나타난 것으로 보인다.
'북코아' 라는, 헌책방을 위한 플랫폼이 국내에 존재하는데, 이런 사례처럼 국내에 있는 독특한 독립 서점들이 모이는 플랫폼이 있을지 모르겠다. 가급적 이용자와 서점 모두 상생할 수 있는 사례가 되었으면 좋겠다.


www.bookjournalism.com/news/22862

 

프랑스, 라이시테의 딜레마 — 북저널리즘 - 젊은 혁신가를 위한 콘텐츠 커뮤니티

프랑스에서 종교 테러가 잇따라 발생하고 있다. 10월 29일 니스에서 발생한 성당 흉기 테러로 3명이 숨졌다. 31일 리옹에서는 그리스 정교회의 사제가 총격 테러를 당해 중태에 빠졌다. 핵심 요약:

www.bookjournalism.com

사람을 위한 종교에 프랑스의 3대 정신인 자유, 평등, 박애라는 단어만큼 적합한 단어가 없다고 생각한다. 최근 이슬람 급진주의자들의 행보는 그들이 종교를 믿는 신자라는 생각을 버리게끔 만들고 있는 것 같다. 신의 위대함을 부르짖으며 타인에게 해를 끼친다면 누가 그 신을 믿고 따를 수 있을까? 어쩌면 자신을 믿지 않으면 지옥에 갈 것이라 말하는 누군가의 신을 보는 것 같은 느낌이 든다.
 갈수록 각박해지는 세상에 극단주의자들의 행보가 더 눈에 띄게 나타나는 듯하다. 개인적으로 제정 분리를 표방하는 라이시테가 어째서 이렇게 반발을 맞이하는지에 대해서는 잘 이해가 가지 않는다. 어째서 개인의 종교에 만족하지 않고 타인의 종교를 박해하는 쪽으로 행동하는 걸까?

728x90
728x90

www.bookjournalism.com/news/22787

 

‘구하라 법’을 구하라 — 북저널리즘 - 젊은 혁신가를 위한 콘텐츠 커뮤니티

자녀 양육을 외면했던 부모가 자녀의 재산을 상속받지 못하게 하는 이른바 구하라 법 에 대한 관심이 다시 높아지고 있다. 법안을 재발의한 더불어민주당 서영교 의원은 1일 보도 자료를 내고

www.bookjournalism.com

 상속이란 자신이 평생 쌓아온 것을 넘겨주는 것이기에 그만큼 큰 의미를 갖는다고 생각한다. 그렇기에 구하라법이 이제서라도 제출된 것에 대해 빠른 처리가 되었으면 한다. 십 몇년간을 연락 한 번 없이 지내왔다면 아무리 가까운 혈육이라도 이제는 남이라 부를 정도의 사이라고 해도 될 정도인데, 자식의 삶에 존재하지도 않았던 사람이 죽고 나서야 자신의 지분을 요구하는 모습은 사람이 얼마나 돈 앞에서 뻔뻔해질 수 있는지를 보여주는 사례라고 생각한다.
 '해태'라는 표현이 주관적이기에 논란이 되지만 명료한 기준 역시 문제의 소지가 될 가능성이 크다. 의도적으로 연락을 끊어놓고 기준이 되지 않을 때까지 기다리다, 그 기준을 들먹이는 사례 역시 나타날 수 있을까 걱정되는 면이 있다. 기존에 있던 소송 기록이나, 설문조사를 통한 의견 수렴을 통해 부양 의무의 해태에 대한 가이드라인을 정해 둔다면 판결에 도움이 될 수 있으리라 생각된다.


www.bookjournalism.com/news/22777

 

왜 ‘빅4’인지 입증한 3분기 — 북저널리즘 - 젊은 혁신가를 위한 콘텐츠 커뮤니티

미국을 대표하는 빅 테크 기업 4곳이 올해 3분기 코로나19 대유행 속에서 영향력을 더 키웠다. 아마존과 알파벳, 페이스북은 역대 최고 실적을 올렸다. 애플은 아이폰 신제품 출시가 연기되면서

www.bookjournalism.com

 미국의 4대 테크 기업인 MAGA와 페이스북은, 코로나로 인한 경제 침체가 우습다는 듯 매출과 시장 영향력을 계속해서 높여가는 모습을 보이고 있다. 물적 판매가 우선되어야 하는 제조 기업들은 상상 이상의 타격을 맞이하고 있지만, 소프트웨어 기업들은 비대면의 이점과 부가 가치 창출 능력을 기반으로 이러한 상황을 어렵지 않게 이겨내는 것 같다. 이러한 현상은 특히 애플의 예를 통해 볼 수 있는데, 애플의 경우 신제품 연기의 영향도 있다지만 핸드폰 매출이 감소한 상태이고, 그럼에도 불구하고 전체 매출은 오히려 증가했음을 알 수 있다.
 갈수록 높아지는 SW서비스 산업의 중요성을 알려주는 사례가 되었다고 볼 수 있다. 아직 개척되지 않은 시장이 많다고 하지만 시장 확장에 있어 제조 산업에는 분명히 한계가 있을 것이다. 하지만 계속해서 다변화된 서비스를 창출 가능한 소프트웨어는 한정된 시장 내에서도 끊임없이 새로운 가치 창출을 가능하게 할 것이다.

728x90
728x90

www.bookjournalism.com/news/22700

 

지구를 위한 기후 미식가 — 북저널리즘 - 젊은 혁신가를 위한 콘텐츠 커뮤니티

세계 채식 장려 캠페인 비거뉴어리(Veganuary) 참가자가 100만 명을 돌파했다. 비거뉴어리는 영어로 완전한 채식주의자를 뜻하는 비건(Vegan) 과 1월을 뜻하는 재뉴어리(January) 를 합한 말이다. 새해를

www.bookjournalism.com

 축산업 운영을 위한 환경 오염이 심각하다는 뉴스를 종종 본 기억이 있다. 하지만 식물성만으로는 채울 수 없는 동물성 단백의 이점과, 축산 산업이 갖는 규모를 생각하면 이를 하루 아침에 배제할 수는 없는 노릇이다.

 그렇기에 최근 배양육 등을 이용해 고기를 대체하고자 하는 시도가 하루빨리 기존 육류의 식감과 경제성 모두에 경쟁력을 갖는 시기가 왔으면 한다. 환경을 생각해 육식을 멀리하고자 하는 비건들에게 환경을 지키면서도 식단의 다양성을 지킬 수 있는 제 3의 선택지가 주어지는 시기가 올 수 있었으면 한다.

 이 기사를 통해 비거뉴어리를 처음 알게 되었다. 비건식으로 넘어갈 생각은 전혀 없지만 식단에 단기적인 변화를 줄 수 있다는 점에서 생각해보면 한 번쯤은 할 만한 시도가 될 듯하다.


www.bookjournalism.com/news/22702

 

킥라니를 만난 적 있나요 — 북저널리즘 - 젊은 혁신가를 위한 콘텐츠 커뮤니티

다음 달부터 전동 킥보드 규제가 완화된다. 만 13세 이상이면 면허증 없이도 탈 수 있도록 하는 법이 12월 10일부터 시행된다. 최근 높아진 인기를 반영해서다. 전국의 공유 전동 킥보드 수는 5만

www.bookjournalism.com

 많은 기술들은 사람에게 편의를 제공하는 쪽으로 발전한다. 전동킥보드 역시 이 예시 중 하나라고 할 수 있겠다. 대중교통이 제공하지 못하는 단거리 이동을 편하게 제공하면서도 자전거와 달리 체력을 요하지 않는다는 장점이 있으니 말이다.
 관련 법안이 통과되고 플랫폼 산업이 발전하는 등 새로운 기술을 누릴 여지와 산업 파이가 늘어나는 것은 환영할 일이라고 생각한다. 하지만 문제는 새로운 사용자들과 기존 규칙 사이의 충돌을 중재할 방법도 고려가 충분히 되어야 한다고 생각한다.
 차량은 사고가 나면 어지간히 심각하지 않은 이상 차만 부서지고 끝이지만, 오토바이는 조금만 부딛혀도 한 두군데 나갈 걱정을 해야 한다는 글을 본 적이 있다. 전동 킥보드는 어떻게 보면 오토바이보다도 더 사고에 대한 위험성이 많다는 점을 생각하면 이를 보완하기 위한 수단이 충분히 고려되어야 할 것 같다. 가령 1인 이상이 탑승했을때는 아예 주행을 못하게 한다던

728x90
728x90

 

www.notion.so/12-2df4d5ce858744748b622b59e4a4b692?fbclid=IwAR3wgCpaRJNQ-DWUkqQquFI5L6c5xGEJiDe4ZY692DMm-TFf-EIMmuCXSmQ

 

뉴스 같이 읽기 모임 12기 모집

지금까지 약 800명의 독자분들이 뉴스 읽기 습관을 함께 만들기 위해 노력해왔어요!

www.notion.so

- T아카데미, 코엑스 행사들, 한빛미디어의 도서 리뷰 등 기술적 인사이트를 얻을 수 있는 행사는 많이 알아보고, 알아본 만큼 발 바쁘게 돌아다니곤 했다.

- 이번 활동은 페이스북을 통해 우연히 접할 수 있는 활동이었는데, 취업 면에서든 혹은 교양 면에서든 소위 '세상 돌아가는 일'에 대해 관심을 가져야 한다는 걸 알면서도 그럴 시간을 좀처럼 내질 못했다.

- 이런 타이틀이 걸린 활동을 하는게 활 의욕을 만드는데는 제격이라고 생각해서 신청하게 되었다. 마침 별도의 모임을 갖는다거나 시간을 많이 할애할 일도 없을 듯하여 고민 없이 신청할 수 있었던 것 같다. 미션은 북저널리즘 사이트에 의견을 댓글로 다는 식으로 운영하는 것 같은데. 그것과 더불어 뉴스와 내 의견을 블로그에도 추가로 올려볼 생각이다.

728x90
728x90
2020 국제 인공지능대전
  • 코로나19로 인해 유명 박람회들이 죄다 연기, 혹은 취소되는 상황에 올해가 끝나가는 이제야 참가할만한 기술 박람회를 맞이할 수 있게 되었다. 한국전자전은 내년으로 연기되었지만, 반도체대전은 올해 개최된다는 것을 보고 거리는 다소 있지만 참관을 결정하게 되었다. 이와 함께 마침 일정이 겹치게 되어 2020 국제인공지능대전도 같이 둘러보기로 했다.

  • 다만 경제 상황이 악화되었던게 문제인지, 작년에 비해서 규모나 분위기가 많이 위축되었다는 점이 많이 느껴져 아쉬움이 남았다. 보통은 전시 마지막날 참관을 하곤 했는데, 올해는 어쩌다 보니 개최 첫날 오전 타임이어서 그럴지도 모른다는 생각이 들었지만, 사회적 거리두기와 맞물려 박람회에 방문한 사람 수가 줄었다는 느낌은 어쩔 수 없는 것 같았다.


2020 국제 인공지능대전

  • 국제인공지능대전에서는 AI와 관련된 HW 및 SW 등 다양한 서비스를 제공하는 기업들을 만나볼 수 있었다. 크게 AI 학습용 GPU서버(Nvidia와 협력 관계를 맺는 회사들이 종종 보였다.), 데이터 학습 및 가공, 그리고 AI모델을 서비스로 제공하는 회사로 크게 분류할 수 있었을 것 같다.
  • 특이했던 점은 기업 대부분이 소규모 혹은 스타트업에 가까웠다는 점이다. 그만큼 AI의 힘을 빌어 핀포인트로 제공 가능한 서비스가 많아졌고, 그와 더불어 AI로 창출 가능한 사업 가능성이 다변화되었음을 의미하는 것 같았다.
  • 기억에 남는 기업이 두 곳 있었는데, 하나는 인피닉이라는 기업이었다. 기존에는 임베디드 및 QA서비스 제공을 하다가, 최근 데이터 관리 사업을 시작한 것으로 보인다. 데이터 수집부터 QA까지 전반적인 전반적인 구축 시스템을 제공하며, 박람회에서는 그 결과물로 영상처리를 기반으로 상품 목록을 자동 인식하는 무인 점포 시스템을 시연 중이었다.

  • 또하나의 기업은 코어닷투데이라는 기업이었다. 이곳의 컨셉은 데이터 스토리텔링이라는 개념이었는데, 내가 어떠한 데이터를 분석한 방식을 Jupyter Notebook을 이용해 업로드하여 사람들에게 공유하는 사이트였다. 어쩌면 Kaggle과 유사한 형태인데, 차이점이라면 Kaggle은 기업이 제시한 내용을 해결하는 곳이라면, 이곳은 이용자들이 자신의 주제로 분석하는 과정을 업로드하는 곳이었다. 자기 이론에 맞게 데이터를 분석할 수 있기 때문에 정보의 자유도가 더 높아질 수 있을 것 같고, 좀 더 사용자 중심적일 수 있다는 장점이 돋보이는 서비스라고 생각했다.

2020 반도체대전

  • SEDEX에서 가장 기억에 남았던 기업은 파스텍이라는 기업으로, 모터 및 컨트롤러 전문 개발 업체였다. 반도체 장비는 극한의 정밀도를 필요로 하는 만큼 로봇에 사용되는 모터 등의 정밀한 제어가 필수적이다. 모터 토크 유지, 3축 등 다양한 방향으로의 정밀 제어를 시연하는 기업이었다.

  • 반도체대전 역시 작년에 비해 아쉬움이 좀 있었는데, 장비나 기술 시연의 규모가 상당히 줄었다는 느낌이 들었다. 그나마 하이닉스/삼성이 자리했고, 램리서치의 경우 간단한 기업 소개 정도만 남아 있는 모습이었다. 거의 기업 시연보다는 해당 박람회에서 기업 간 미팅을 위한 자리를 마련한 곳이 대부분이었던 것 같다.
728x90
728x90
  • 한빛미디어의 '나는 리뷰어다 2020' 에 선정되어 도서를 지원받아 작성한 글입니다.

  • 지난번에 파이썬으로 배우는 딥러닝 교과서를 리뷰했었는데, 이번 리뷰도서로 또 다시 딥러닝 책을 받게 되었다. 그렇게 된 만큼 두 책의 차이 중심으로 설명을 해보고자 한다. 이번 책은 쿡북, 지난번에 리뷰한 책은 교과서로 통칭하고자 한다.
  • 쿡북의 장점은 방대한 '레시피' 이다. 머신러닝에 가장 보편적으로 사용되는 numpy, pandas, scikit-learn 삼총사에 대한 방대한 사용 케이스를 상세히 설명했고, 각 단계별로 차근차근 밟아가는 것이 장점이다. 각 코드마다 레퍼런스 링크도 참조되어 있으니(이 부분은 전자책으로 보면 더 좋을 것으로 보인다) 거기서 한 걸음 더 밟아가고자 하는 이들에게 유용할 것으로 보인다.
  • 파이썬, 혹은 머신러닝에 대한 기초 이론이 필요하다면 교과서 쪽이 조금 더 우세할 것으로 보인다. 내용 설명도 상당히 친절한 편이고, 쿡북 대비로는 아쉬울 수 있지만 이 책도 충분히 괜찮은 머신러닝 라이브러리 자료를 담고 있다.
  • 이론부터 차근차근 밟아가는 걸 좋아하는 사람이 있는가 하면, 나처럼 빠른 실전을 더 선호하는 사람도 있을 것으로 보인다. 개인적으로는 전자는 교과서, 후자는 이 쿡북 책이 더 좋을 것으로 보인다. 지난번에 본 교과서도 마음에 들었지만, 내가 공부한다면 이 책으로 내용을 진행할 것 같다.

www.aladin.co.kr/shop/wproduct.aspx?ItemId=204204038

 

파이썬을 활용한 머신러닝 쿡북

일상적인 머신러닝 작업에서 발생하는 문제를 해결하는 데 필요한 각종 세부사항을 다룬다. 데이터 과학자와 머신러닝 엔지니어가 모델을 만들면서 가장 많이 사용하는 작업에 필요한 거의 200�

www.aladin.co.kr

www.aladin.co.kr/shop/wproduct.aspx?ItemId=233731362

 

파이썬으로 배우는 딥러닝 교과서

이미지 인식 모델을 만드는 과정을 다루면서 딥러닝 요소를 학습한다. 머신러닝 기본부터 파이썬 기초와 함수 사용법을 배우고, 팬더스로 행렬 계산에 특화된 넘파이와 데이터를 반복적으로 다

www.aladin.co.kr

 

728x90
728x90
프로그래머스 과제관 참관기 [[앱-Android] 뮤직 플레이어 앱]

프로그래머스 과제관 참관기 [[앱-Android] 뮤직 플레이어 앱]

  • 졸업작품을 위해 어플리케이션을 만들어야 해서 공부하던 중 프로그래머스 과제관의 존재를 알게 되었다.
  • 이론도 좋지만 실제 작품을 하나 만들어보는 과정을 통해 안드로이드 개발에 필요한 요소들을 알아보고자 안드로이드 어플 제작에 도전해보게 되었다. 빨리 끝날 것 같은 예상과는 달리 12시 ~ 익일 새벽 5시까지 이틀, 총 34시간 정도를 쓴 것 같다.
  • FLO 어플리케이션을 제작하는 프로젝트로, 요구사항은 다음과 같았다.

화면 구성 요소

  • 스플래시 스크린
  • 음악 재생 화면
    • 재생 중인 음악 정보(제목, 가수, 앨범 커버 이미지, 앨범명)
    • 현재 재생 중인 부분의 가사 하이라이팅
    • Seekbar
    • Play/Stop 버튼
  • 전체 가사 보기 화면
    • 특정 가사로 이동할 수 있는 토글 버튼
    • 전체 가사 화면 닫기 버튼
    • Seekbar
    • Play/Stop 버튼

기능 요구

  • 스플래시 스크린
    • 제공되는 이미지를 2초간 노출 후 음악 재생 화면으로 전환시킵니다.
  • 음악 재생 화면
    • 주어진 노래의 재생 화면이 노출됩니다.
    • 앨범 커버 이미지, 앨범명, 아티스트명, 곡명이 함께 보여야 합니다.
    • 재생 버튼을 누르면 음악이 재생됩니다. (1개의 음악 파일을 제공할 예정)
    • 재생 시 현재 재생되고 있는 구간대의 가사가 실시간으로 표시됩니다.
    • 정지 버튼을 누르면 재생 중이던 음악이 멈춥니다.
    • seekbar를 조작하여 재생 시작 시점을 이동시킬 수 있습니다.
  • 전체 가사 보기 화면
    • 전체 가사가 띄워진 화면이 있으며, 특정 가사 부분으로 이동할 수 있는 토글 버튼이 존재합니다.
    • 토글 버튼 on: 특정 가사 터치 시 해당 구간부터 재생
    • 토글 버튼 off: 특정 가사 터치 시 전체 가사 화면 닫기
    • 전체 가사 화면 닫기 버튼이 있습니다.
    • 현재 재생 중인 부분의 가사가 하이라이팅 됩니다.
  • 곡 정보 데이터
    • singer: 아티스트명
    • album: 앨범명
    • title: 곡명
    • image: 앨범 커버 이미지
    • file: mp3 파일의 링크
    • lyrics: 시간으로 구분 된 가사. 가사의 각 줄 마다 해당 가사가 표시되기 시작되어야 할 시간이 분:초:밀리초 단위로 적혀 있으며, 이를 활용하여 현재 재생되는 곡의 가사를 표시해야 합니다.

완성 화면

MainActivity

  • 스플래시 스크린의 경우 Handler.postDelayed를 통해 2초 후 다음 액티비티를 호출하는 식으로 빠르게 구현 가능했다.
  • 메인 화면에서 데이터는 json 코드를 읽어들여야 했다. 처음에는 안드로이드 책의 http 읽는 예제를 썼다가, 나중에 OkHttp로 바꾸어 작성했다.
val client = OkHttpClient() val request = Request.Builder().url(FLOdata.urlJson).build() client.newCall(request).enqueue(object : Callback { override fun onFailure(call: Call, e: IOException) { Log.e("Error", "Failure!") } override fun onResponse(call: Call, response: Response) { val strJson = response?.body?.string() val gson = Gson() val FLOData: FLOJson = gson.fromJson(strJson, FLOJson::class.java) val image = Glide.with(this@MainActivity).load(FLOData.image) FLOdata.duration = FLOData.duration FLOdata.fileURL = FLOData.file parseLyrics(FLOData.lyrics) runOnUiThread { if (FLOData != null) { textTitle.text = FLOData.title textArtist.text = FLOData.singer textAlbum.text = FLOData.album textDuration.text = "${(FLOdata.duration / 60)}:${(FLOdata.duration % 60)}" image.into(imageAlbumArt) seekBar.max = FLOdata.duration } } } })
  • 읽어들인 데이터는 먼저 Gson으로 파싱하기로 했다. 이때 데이터는 두 액티비티(메인, 가사화면)을 공유해야 하기 때문에, 컴패니언 오브젝트를 사용했다. 원래는 mediaplayer를 서비스로 구현하는 식으로 해야 했는데, 어댑터로 구현 후 바꾸기에는 시간이 너무 촉박한 상황이라(시험기간이다 지금 ㅜㅜ...) 바람직한 방식은 아니라고 생각했지만 어쩔수 없이 해당 방식으로 구현하기로 했다.
class FLOdata{ companion object { val urlJson = URL("https://grepp-programmers-challenges.s3.ap-northeast-2.amazonaws.com/2020-flo/song.json") var duration: Int = 0 //sec length data var fileURL: String = "" var lyrics = arrayListOf<String>() var mediaPlayer: MediaPlayer? = null var pausePosition: Int = 0 //ms time data var statePlaying: Boolean = false var timeline = arrayListOf<Int>() var timeindex = -1 } }
  • 재생버튼을 누르면, mediaplayer가 null인 경우 생성하고, 그렇지 않으면 시간에 따라 적절하게 동작하게 한다.
  • 마지막으로 가사창을 누르면 가사 액티비티로 넘어가게 했다.
textLyrics.setOnClickListener() { val intent = Intent(this@MainActivity, FullLyricsActivity::class.java) startActivity(intent) }

가사 Activity

  • 가사의 경우 색을 바꿔야 하고, 리스트뷰 구현이 필요해 리스트뷰를 커스텀하여 진행했다.
<!--activity_full_lyrics.xml--> <?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#131010" tools:context=".MainActivity" tools:ignore="UseSwitchCompatOrMaterialXml"> <ScrollView android:id="@+id/scrollView2" android:layout_width="0dp" android:layout_height="0dp" android:layout_marginStart="16dp" android:layout_marginTop="16dp" android:layout_marginEnd="16dp" android:layout_marginBottom="16dp" android:fillViewport="true" app:layout_constraintBottom_toTopOf="@+id/seekBar2" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <ListView android:id="@+id/ListLyrics" android:layout_width="match_parent" android:layout_height="match_parent" android:divider="#66FFFFFF" android:dividerHeight="2dp" android:textColor="#FFFFFF" android:entries="@array/list_lyrics" android:textSize="12sp" /> </LinearLayout> </ScrollView> <ImageButton android:id="@+id/imageButton2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="16dp" android:layout_marginBottom="16dp" android:background="@drawable/ic_baseline_play_arrow_24" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/seekBar2" tools:ignore="VectorDrawableCompat" /> <SeekBar android:id="@+id/seekBar2" android:layout_width="0dp" android:layout_height="18dp" android:layout_marginStart="16dp" android:layout_marginTop="8dp" android:layout_marginEnd="16dp" android:progress="0" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.1" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/scrollView2" /> <Switch android:id="@+id/switch1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="16dp" android:layout_marginEnd="16dp" android:layout_marginBottom="16dp" android:text="Switch" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toBottomOf="@+id/seekBar2" /> <ImageButton android:id="@+id/imageButton3" android:layout_width="64dp" android:layout_height="64dp" android:layout_marginStart="16dp" android:layout_marginTop="16dp" android:layout_marginBottom="16dp" android:background="#00FFFFFF" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/seekBar2" app:srcCompat="@android:drawable/ic_menu_close_clear_cancel" /> </androidx.constraintlayout.widget.ConstraintLayout> <!--custom_layout.xml--> <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="1dp" android:background="#000000" android:orientation="vertical" android:padding="8dp"> <TextView android:id="@+id/lyricsLine" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:background="#000000" android:textColor="#FFFFFF" android:textSize="14sp" /> </LinearLayout>
  • 리스트뷰 아이템 색을 바꾸는거도 커스텀이 필요한 것 같다. 그거 없이 할 방법을 찾아봤는데 도저히 보이질 않았다 ㅜㅜ...
  • 가사 액티비티의 동작은 거의 유사하지만, 가사 터치에 대한 동작 구현 정도가 차이일 것 같다. 먼저 가사를 터치할 경우 switch 상태에 따라 해당 가사 time으로 이동하거나, 해당 화면이 꺼지게 구현했다.
ListLyrics.adapter = mAdapter ListLyrics.setOnItemClickListener(OnItemClickListener { _, _, position, _ -> if(!toggle){ FLOdata.pausePosition = FLOdata.timeline.get(position) seekBar2.progress = FLOdata.pausePosition / 1000 FLOdata.mediaPlayer?.seekTo(FLOdata.pausePosition) } else { handler.removeCallbacks(runnable) finish() } })

후기

  • 정말 힘들었다. 안드로이드에 대한 지식 기반도 없이 바로 부딪히다 보니 오류 하나에도 해메는게 너무 크게 느껴졌다.

  • 단순한 로직 구현은 생각보다 쉽게 할 수 있었다. 다만 하드웨어적 기능 구현으로 넘어가자마자 난이도가 수직상승하는 기분을 느꼈다.

  • 코틀린 언어 자체는 할만한 언어인데, 안드로이드의 구조적인 특징(백그라운드는 서비스로 구현해야 한다, 안드로이드 성능을 위해 백그라운드 동작에는 많은 제약이 존재) 등으로 인해 기능 구현 하나에도 신경써야 할 점이 상당히 많다는 게 느껴졌다.

  • 단순히 코드 레퍼런스만 찾지 말고, 공식 문서를 실제 코드로 응용하는 능력을 빨리 기를 필요가 있을 것 같다. 남들은 다 된다는데 나만 안되는 경우 대처하기가 너무 힘들었다...

728x90

+ Recent posts