안드로이드에서 FFmpeg를 사용할 필요가 있어서 사용법을 검색해봤는데 대부분 NDK를 이용해서 FFmpeg를 빌드하여 FFmpeg를 사용했다.

 

 물론 이렇게 하면 FFmpeg를 사용할 수 있지만 생각보다 간단하지는 않다. 그래서 간단하게 사용할 수 있는 방법을 찾아보았는데 아래 사이트에서 모바일에서 사용할 수 있는 FFmpeg라이브러리인 MobileFFmpeg를 만들어놓았다.

 

https://github.com/tanersener/mobile-ffmpeg

 

사용법은 간단하다.

 

먼저 build.gradle(Module: app)에 아래와 같이 추가한다.

dependencies {
    implementation 'com.arthenica:mobile-ffmpeg-full:4.2.2'
}

 

※ 만약 SDK 버전이 23 이하라면 아래와 같이 추가한다.

dependencies {
    implementation 'com.arthenica:mobile-ffmpeg-full:4.2.2.LTS'
}

 

이제 사용하고자 하는 곳에 아래와 같이 라이브러리를 추가하고 함수를 사용하면 된다.

import com.arthenica.mobileffmpeg.FFmpeg

FFmpeg.execute("-i file1.mp4 -c:v mpeg4 file2.mp4") // 파일은 경로를 포함해서 써야한다. 

 

자세한 정보는 위 사이트에서 README.md로 제공하고 있다.

'Android' 카테고리의 다른 글

[Android] EditText에 이미지 추가  (0) 2019.10.27
[Android Kotlin] 음성 녹음  (0) 2019.10.04

다음 사이트를 참고하여 Ubuntu 18.04에서 MySQL 8.0을 설치하였다.

 

https://www.fosstechnix.com/how-to-install-mysql-8-in-ubuntu/

 

How to Install MySQL 8.0 on Ubuntu 18.04 / 16.04 - FOSS TechNix

In this article, We are going to demonstrate installation of latest MySQL 8.0 database server on Ubuntu 18.04 Bionic Beaver step by step using command line.

www.fosstechnix.com

 

MySQL 설치 순서는 다음과 같다.

 

1. MySQL APT Repository 추가

sudo wget https://dev.mysql.com/get/mysql-apt-config_0.8.13-1_all.deb

 

Repository 버전은 아래 MySQL 사이트 하단에 보이는 버전을 추가하였다.

 

https://dev.mysql.com/downloads/repo/apt/

 

 

2. MySQL APT Repository 패키지 다운로드

sudo dpkg -i mysql-apt-config_0.8.13-1_all.deb

 

위의 명령어를 입력하면 아래와 같은 창이 뜨는데 OK를 선택하면 된다.

 

 

3. MySQL Repository 업데이트

sudo apt-get update

 

4. MySQL 8.0 Server 설치

sudo apt-get install mysql-server

 

위의 명령어를 입력하면 아래와 같이 창이 뜨는데 root 계정에서 사용할 비밀번호를 입력해주면 된다.

 

한 번 더 입력해준다.

그리고 아래와 같은 창이 뜰텐데 Use Strong Password Encrypthon을 선택한다.

 

 

5. mysql_secure_installation 설정

mysql_secure_installation

 

보안과 관련된 설정을 하기 위해 위의 명령어를 입력하면 방금 전에 설정한 root 계정의 비밀번호를 입력하라고 나온다. 

 

root 계정의 비밀번호를 입력하고 나면  아래와 같이 몇 가지 보안과 관련된 설정을 하게 되는데 상황에 맞게 설정하면 된다.

 

참고로 나는 아래와 같이 설정하였다.


Securing the MySQL server deployment.

Enter password for user root: 

VALIDATE PASSWORD COMPONENT can be used to test passwords
and improve security. It checks the strength of password
and allows the users to set only those passwords which are
secure enough. Would you like to setup VALIDATE PASSWORD component?

Press y|Y for Yes, any other key for No: N
Using existing password for root.
Change the password for root ? ((Press y|Y for Yes, any other key for No) : N

 ... skipping.
By default, a MySQL installation has an anonymous user,
allowing anyone to log into MySQL without having to have
a user account created for them. This is intended only for
testing, and to make the installation go a bit smoother.
You should remove them before moving into a production
environment.

Remove anonymous users? (Press y|Y for Yes, any other key for No) : Y
Success.


Normally, root should only be allowed to connect from
'localhost'. This ensures that someone cannot guess at
the root password from the network.

Disallow root login remotely? (Press y|Y for Yes, any other key for No) : N

 ... skipping.
By default, MySQL comes with a database named 'test' that
anyone can access. This is also intended only for testing,
and should be removed before moving into a production
environment.


Remove test database and access to it? (Press y|Y for Yes, any other key for No) : Y
 - Dropping test database...
Success.

 - Removing privileges on test database...
Success.

Reloading the privilege tables will ensure that all changes
made so far will take effect immediately.

Reload privilege tables now? (Press y|Y for Yes, any other key for No) : Y
Success.

All done!

 

6. root 계정으로 MySQL에 로그인

mysql -u root -p

 

이로써 MySQL 설치가 완료되었다. 추가로 MySQL 서비스와 관련된 명령어는 아래와 같다.

 

MySQL 서비스 시작

sudo systemctl start mysql.service

MySQL 서비스 중지

sudo systemctl stop mysql.service

MySQL 서비스 재시작

sudo systemctl restart mysql.service

MySQL 서비스 상태 검사

sudo systemctl status mysql.service

 

진행하고 있는 프로젝트 중에 Webcam 영상 데이터를 서버로 보낼 필요가 있어 자료를 조사하기 시작했다.

 

그리고 자료를 조사하던 중 아래 사이트에서 Webcam 영상 데이터를 OpenCV를 이용해 보낼 수 있는 코드를 발견했다.

 

https://stackoverflow.com/questions/46912475/python-webcam-stream-over-udp-socket?rq=1

 

Python webcam stream over Udp socket

im trying to make a webcam stream over two computers in the same network, so i did some research on the internet and i found this client and server code this is the Client import socket import num...

stackoverflow.com

해당 코드는 Python2를 기준으로 작성되어있어서 Python3에서 사용할 수 있게 조금 코드를 변경했다. 아래는 변경한 코드이다.

 

Client

import socket
import cv2

UDP_IP = '127.0.0.1'
UDP_PORT = 9505

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

cap = cv2.VideoCapture(0)

while True:
    ret, frame = cap.read()
    d = frame.flatten()
    s = d.tostring()

    for i in range(20):
        sock.sendto(s[i*46080:(i+1)*46080], (UDP_IP, UDP_PORT))

        if cv2.waitKey(1) & 0xFF == ord('q'):
            break

 

Server

import socket
import numpy
import cv2

UDP_IP = "127.0.0.1"
UDP_PORT = 9505

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind((UDP_IP, UDP_PORT))

s = b''

while True:
    data, addr = sock.recvfrom(46080)
    s += data

    if len(s) == (46080 * 20):
        frame = numpy.fromstring(s, dtype=numpy.uint8)
        frame = frame.reshape(480, 640, 3)
        cv2.imshow("frame", frame)
        s = b''

        if cv2.waitKey(1) & 0xFF == ord('q'):
            cv2.destroyAllWindows()
            break

 

※ 참고로 위의 코드에서 46080이 자주 나오는데 이것이 의미하는 바는 다음과 같다.

Client의 Webcam에서 생성하는 각 프레임은 640x480 RGB 픽셀을 가지는데 이것의 실제 데이터 크기는 640 x 480 x 3 = 921,600 Byte이다. 이 때 3은 RGB 즉, 빨강, 초록,  파랑을 나타내기 위해 사용하는 것이다.

 

그런데 UDP는 한번에 데이터를 65,535 Byte 까지 보낼 수 있어 위의 921,600 Byte를 한 번에 보낼 수 없다. 그래서 데이터를 나눠서 보내야하는데 해당 코드에서는 921,600 Byte를 20으로 나눈 46,080 Byte를 보내주고 있다. 

 

그래서 46080이 코드에서 계속 나오는 것이다. 

 

그래서 만약 OpenCV에서 생성하는 프레임이 다르다면 그에 맞게 고쳐주면 된다.

 

실행해보면 실행은 되나 영상이 조금씩 내려가는 현상을 볼 수 있는데 원인은 UDP 프로토콜의 특성 때문이다. 서버로 가는 데이터 중 일부를 못 받아도 그냥 무시하고 데이터의 순서가 잘못되어있더라도 데이터를 받는 순서대로 이미지를 생성하기 떄문이다.

 

그래서 이를 해결하기 위해 코드를 다음과 같이 수정했다.

 

Client

import socket
import cv2

UDP_IP = '127.0.0.1'
UDP_PORT = 9505

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

cap = cv2.VideoCapture(0)

while True:
    ret, frame = cap.read()
    d = frame.flatten()
    s = d.tostring()

    for i in range(20):
        sock.sendto(bytes([i]) + s[i*46080:(i+1)*46080], (UDP_IP, UDP_PORT))

 

        if cv2.waitKey(1) & 0xFF == ord('q'):
            break

 

Server

import socket
import numpy
import cv2

UDP_IP = "127.0.0.1"
UDP_PORT = 9505

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind((UDP_IP, UDP_PORT))

s = [b'\xff' * 46080 for x in range(20)]

fourcc = cv2.VideoWriter_fourcc(*'DIVX')
out = cv2.VideoWriter('output.avi', fourcc, 25.0, (640, 480))

while True:
    picture = b''

    data, addr = sock.recvfrom(46081)
    s[data[0]] = data[1:46081]

    if data[0] == 19:
        for i in range(20):
            picture += s[i]

        frame = numpy.fromstring(picture, dtype=numpy.uint8)
        frame = frame.reshape(480, 640, 3)
        cv2.imshow("frame", frame)
        out.write(frame)

        if cv2.waitKey(1) & 0xFF == ord('q'):
            cv2.destroyAllWindows()
            break

 

코드를 보면 Client에서 데이터를 보낼 때 앞의 1 Byte에 0 ~ 19까지의 숫자를 포함시켜 보냈는데 이는 Server에게 해당 데이터가 프레임의 어디 부분의 데이터인지 알려주기 위해서이다.

 

그리고 Server에서는 크기가 20인 프레임에 대한 리스트를 만들어 Client에게서 데이터를 받으면 앞의 1 Byte를 읽어 s[data[0]] = data[1:46081]와 같이 리스트의 해당 위치에 앞의 1 Byte를 제외한 나머지 데이터를 할당한다.

 

그리고 앞의 1 Byte가 19 즉, 프레임의 마지막 데이터이면 리스트의 데이터들을 전부 합쳐 이미지로 보여주게 했다.

 

그리고 이번에는 서버에서 보여지는 영상이 서버에 저장될 수 있도록 VideoWriter 함수를 사용해서 Server에 대한 코드가 있는 곳에 output.avi라는 파일로 저장하게 하였다.

 

실제 실행시켜보면 이전의 코드에서 발생한 영상이 조금씩 내려가는 현상이 사라진 것을 볼 수 있다.

'Language > Python' 카테고리의 다른 글

[Python] 파일 크기 구하기  (0) 2019.09.25

+ Recent posts