• Tidak ada hasil yang ditemukan

4. IMPLEMENTASI SISTEM

N/A
N/A
Protected

Academic year: 2021

Membagikan "4. IMPLEMENTASI SISTEM"

Copied!
13
0
0

Teks penuh

(1)

21

Universitas Kristen Petra

4. IMPLEMENTASI SISTEM

Pada bab ini akan dibahas tentang implementasi sistem sesuai dengan

analisa dan desain sistem yang sudah dibuat pada bab sebelumnya.

4.1.

Implementasi Aplikasi yang digunakan

Pembuatan aplikasi dalam skripsi ini membutuhkan beberapa

software

penunjang, sebagai berkikut:

Android

Studio dengan versi 3.2.1 ,digunakan sebagai aplikasi

Intergrated Development Enviroment, untuk memudahkan pembuatan

aplikasi.

Thorn

merupakan

tool yang yang digunakan sebagai

editor

untuk

bahasa pemograman python.

4.2.

Implementasi Program

Implementasi program adalah tahap penerapan rancangan sistem

berdasarkan desain yang telah dibuat menjadi sebuah aplikasi.

Tabel 4.1

Tabel Relasi Program

Proses

Segmen Program

Source Code start

Segmen Program 4.11

Source Code Menampilkan notifikasi

Segmen Program 4.12

Source Code Mirroring layar smartphone

Segmen Program 4.13

Source Code Connect

ke Raspberry Pi

melalui Micro USB

Segmen Program 4.14

Source Code Connect

ke Raspberry Pi

melalui Wi-fi

Segmen Program 4.15

Source Code Connect ke Aplikasi Android

melalui Wi-fi

Segmen Program 4.16

Source Code Connect ke Aplikasi Android

melalui Micro-USB

(2)

4.3.

Implementasi Program Android

4.3.1.

Start

Source code ini dijalankan setelah

user menekan tombol start di aplikasi.

Source code ini terdapat di Segmen Program 4.11.

Source Code start

public int onStartCommand(Intent intent, int flags, int startId) { if (intent == null) { return START_NOT_STICKY; } mReceiverIp = intent.getStringExtra(Common.EXTRA_RECEIVER_IP); mResultCode = intent.getIntExtra(Common.EXTRA_RESULT_CODE, -1); mResultData = intent.getParcelableExtra(Common.EXTRA_RESULT_DATA); Log.d(TAG, "Remove IP: " + mReceiverIp); if (mReceiverIp == null) {

return START_NOT_STICKY; }

//if (mResultCode != Activity.RESULT_OK || mResultData == null) { // Log.e(TAG, "Failed to start service, mResultCode: " + mResultCode + ", mResultData: " + mResultData);

// return START_NOT_STICKY; //} mSelectedWidth = intent.getIntExtra(Common.EXTRA_SCREEN_WIDTH, Common.DEFAULT_SCREEN_WIDTH); mSelectedHeight = intent.getIntExtra(Common.EXTRA_SCREEN_HEIGHT, Common.DEFAULT_SCREEN_HEIGHT); mSelectedDpi = intent.getIntExtra(Common.EXTRA_SCREEN_DPI, Common.DEFAULT_SCREEN_DPI); mSelectedBitrate = intent.getIntExtra(Common.EXTRA_VIDEO_BITRATE, Common.DEFAULT_VIDEO_BITRATE); mSelectedFormat = intent.getStringExtra(Common.EXTRA_VIDEO_FORMAT); if (mSelectedFormat == null) { mSelectedFormat = Common.DEFAULT_VIDEO_MIME_TYPE; } if (mReceiverIp.length() <= 0) {

Log.d(TAG, "Start with listen mode"); if (!createServerSocket()) {

Log.e(TAG, "Failed to create socket to receiver, ip: " + mReceiverIp);

return START_NOT_STICKY; }

} else {

Log.d(TAG, "Start with client mode"); if (!createSocket()) {

Log.e(TAG, "Failed to create socket to receiver, ip: " + mReceiverIp);

return START_NOT_STICKY; }

if (!startScreenCapture()) {

Log.e(TAG, "Failed to start capture screen"); return START_NOT_STICKY;

} }

return START_STICKY; }

(3)

23

Universitas Kristen Petra

4.3.2.

Notifikasi

Notifikasi digunakan supaya user tidak perlu membuka aplikasi untuk

menghentikan mirroring. Source code untuk notifikasi dapat dilihat pada Segmen

Program 4.1.2

Source Code menampilkan notifikasi

private void showNotification() {

final Intent notificationIntent = new Intent(Common.ACTION_STOP_CAST);

PendingIntent notificationPendingIntent = PendingIntent.getBroadcast(this, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);

Notification.Builder builder = new Notification.Builder(this); builder.setSmallIcon(R.mipmap.ic_launcher) .setDefaults(Notification.DEFAULT_ALL) .setOnlyAlertOnce(true) .setOngoing(true) .setContentTitle(getString(R.string.app_name)) .setContentText(getString(R.string.casting_screen)) .addAction(android.R.drawable.ic_menu_close_clear_cancel, getString(R.string.action_stop), notificationPendingIntent);

NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

notificationManager.notify(NT_ID_CASTING, builder.build()); }

private void dismissNotification() {

NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

(4)

4.3.3.

Mirroring layar smartphone

Pada saat

user

menekan start, aplikasi android langsung melakukan

mirroring yang akan kemudian dikirimkan ke Raspberry Pi.

Source code

mengenai mirroring layar smartphone terdapat di Segmen Program 4.13

Mirroring layar smartphone

private void prepareVideoEncoder() {

mVideoBufferInfo = new MediaCodec.BufferInfo();

MediaFormat format = MediaFormat.createVideoFormat(mSelectedFormat, mSelectedWidth, mSelectedHeight);

int frameRate = Common.DEFAULT_VIDEO_FPS;

// Set some required properties. The media codec may fail if these aren't defined. format.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface); format.setInteger(MediaFormat.KEY_BIT_RATE, mSelectedBitrate); format.setInteger(MediaFormat.KEY_FRAME_RATE, frameRate); format.setInteger(MediaFormat.KEY_CAPTURE_RATE, frameRate); format.setInteger(MediaFormat.KEY_REPEAT_PREVIOUS_FRAME_AFTER, 1000000 / frameRate); format.setInteger(MediaFormat.KEY_CHANNEL_COUNT, 1); format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 1); // 1 seconds between I-frames

// Create a MediaCodec encoder and configure it. Get a Surface we can use for recording into.

try {

mVideoEncoder =

MediaCodec.createEncoderByType(mSelectedFormat);

mVideoEncoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);

mInputSurface = mVideoEncoder.createInputSurface(); mVideoEncoder.start();

} catch (IOException e) {

Log.e(TAG, "Failed to initial encoder, e: " + e); releaseEncoders();

} }

private void startRecording() { Log.d(TAG, "startRecording"); prepareVideoEncoder();

// Start the video input. mVirtualDisplay =

mMediaProjection.createVirtualDisplay("Recording Display", mSelectedWidth,

mSelectedHeight, mSelectedDpi, 0 /* flags */, mInputSurface,

null /* callback */, null /* handler */); // Start the encoders

drainEncoder(); }

(5)

25

Universitas Kristen Petra

private boolean drainEncoder() {

mDrainHandler.removeCallbacks(mDrainEncoderRunnable); while (true) {

int bufferIndex =

mVideoEncoder.dequeueOutputBuffer(mVideoBufferInfo, 0);

if (bufferIndex == MediaCodec.INFO_TRY_AGAIN_LATER) { // nothing available yet

break;

} else if (bufferIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {

// should happen before receiving buffers, and should only happen once

//if (mTrackIndex >= 0) {

// throw new RuntimeException("format changed twice"); //}

//mTrackIndex =

mMuxer.addTrack(mVideoEncoder.getOutputFormat());

//if (!mMuxerStarted && mTrackIndex >= 0) { // mMuxer.start();

// mMuxerStarted = true; //}

} else if (bufferIndex < 0) {

// not sure what's going on, ignore it } else {

ByteBuffer encodedData = mVideoEncoder.getOutputBuffer(bufferIndex); if (encodedData == null) {

throw new RuntimeException("couldn't fetch buffer at index " + bufferIndex);

}

//Log.d(TAG, "Video buffer offset: " +

mVideoBufferInfo.offset + ", size: " + mVideoBufferInfo.size); if (mVideoBufferInfo.size != 0) { encodedData.position(mVideoBufferInfo.offset); encodedData.limit(mVideoBufferInfo.offset + mVideoBufferInfo.size); if (mSocketOutputStream != null) { System.out.println("Jalan : "+ctr); try {

byte[] b = new byte[encodedData.remaining()]; encodedData.get(b); if (mIvfWriter != null) { mIvfWriter.writeFrame(b, mVideoBufferInfo.presentationTimeUs); } else { mSocketOutputStream.write(b); } } catch (IOException e) {

Log.d(TAG, "Failed to write data to socket, stop casting");

e.printStackTrace(); stopScreenCapture(); return false;

(6)

System.out.println("Finish : "+ctr); ctr++; } } mVideoEncoder.releaseOutputBuffer(bufferIndex, false); if ((mVideoBufferInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) { break; } } } //System.out.println("Casting video"); mDrainHandler.postDelayed(mDrainEncoderRunnable, 10); return true; }

(7)

27

Universitas Kristen Petra

4.3.4.

Menghubungkan Aplikasi Android ke Raspberry PI Melalui Micro

USB

Micro USB mode akan menghubungkan aplikasi android ketika

smartphone

terhubung dengan Raspberry Pi melalui kabel

micro USB, dan

menekan tombol start.

Source

code untuk menghubungkan aplikasi android

dengan Raspberry Pi melalui micro USB terdapat di Segmen Program 4.14.

Source Code connect ke Raspberry Pi melalui Micro USB

private boolean createServerSocket() {

Thread th = new Thread(new Runnable() { @Override

public void run() { try {

mServerSocket = new ServerSocket(Common.VIEWER_PORT);

while (!Thread.currentThread().isInterrupted() && !mServerSocket.isClosed()) {

mSocket = mServerSocket.accept(); CommunicationThread commThread = new CommunicationThread(mSocket);

new Thread(commThread).start(); }

} catch (IOException e) {

Log.e(TAG, "Failed to create server socket or server socket error"); e.printStackTrace(); } } }); th.start(); return true; }

class CommunicationThread implements Runnable { private Socket mClientSocket;

public CommunicationThread(Socket clientSocket) { mClientSocket = clientSocket;

}

public void run() {

while (!Thread.currentThread().isInterrupted()) { try {

BufferedReader input = new BufferedReader(new InputStreamReader(mClientSocket.getInputStream()));

String data = input.readLine();

Log.d(TAG, "Got data from socket: " + data); if (data == null || !data.equalsIgnoreCase("mirror")) { mClientSocket.close(); return; } mSocketOutputStream = mClientSocket.getOutputStream();

OutputStreamWriter osw = new OutputStreamWriter(mSocketOutputStream); osw.write(String.format(HTTP_MESSAGE_TEMPLATE, mSelectedWidth, mSelectedHeight)); osw.flush(); mSocketOutputStream.flush(); if

(8)

4.3.5.

Menghubungkan Aplikasi Android ke Raspberry Pi Melalui Wi-fi

User menulis IP address atau memilih dari list kemudian menekan tombol

start untuk melakukan

mirroring.

Source

code untuk menghubungkan aplikasi

android dengan Raspberry Pi melalui Wi-fi terdapat di Segmen Program 4.14.

Source Code Connect ke Raspberry Pi melalui Wi-fi

private boolean createSocket() {

Thread th = new Thread(new Runnable() { @Override

public void run() { try {

InetAddress serverAddr = InetAddress.getByName(mReceiverIp);

mSocket = new Socket(serverAddr, Common.VIEWER_PORT); mSocketOutputStream = mSocket.getOutputStream(); OutputStreamWriter osw = new

OutputStreamWriter(mSocketOutputStream); osw.write(String.format(HTTP_MESSAGE_TEMPLATE, mSelectedWidth, mSelectedHeight)); osw.flush(); mSocketOutputStream.flush(); if (mSelectedFormat.equals(MediaFormat.MIMETYPE_VIDEO_AVC)) {

if (mSelectedWidth == 1280 && mSelectedHeight == 720) {

mSocketOutputStream.write(H264_PREDEFINED_HEADER_1280x720);

} else if (mSelectedWidth == 800 && mSelectedHeight == 480) {

mSocketOutputStream.write(H264_PREDEFINED_HEADER_800x480); } else {

Log.e(TAG, "Unknown width: " + mSelectedWidth + ", height: " + mSelectedHeight); mSocketOutputStream.close(); mSocket.close(); mSocket = null; mSocketOutputStream = null; } } else if (mSelectedFormat.equals(MediaFormat.MIMETYPE_VIDEO_VP8)) {

mIvfWriter = new IvfWriter(mSocketOutputStream, mSelectedWidth, mSelectedHeight);

mIvfWriter.writeHeader(); } else {

Log.e(TAG, "Unknown format: " + mSelectedFormat); mSocketOutputStream.close(); mSocket.close(); mSocket = null; mSocketOutputStream = null; } return; } catch (UnknownHostException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }

(9)

29

Universitas Kristen Petra

mSocket = null; mSocketOutputStream = null; } }); th.start(); try { th.join();

if (mSocket != null && mSocketOutputStream != null) { return true; } } catch (InterruptedException e) { e.printStackTrace(); } return false; }

(10)

4.4.

Implementasi Program Python di Raspberry Pi

4.4.1.

Menghubungkan Raspberry Pi ke Aplikasi Android Melalui Wi-fi

Raspberry Pi akan menampilkan diri di list dalam aplikasi android dan

ketika user menekan Raspberry Pi yang tampil di list app nya dan menekan start

maka Raspberry Pi akan menerima frame yang dikirim dari aplikasi android.

Source Code Raspberry Pi ke Android Melalui Wi-fi.

Source Code Connect ke Aplikasi Android melalui Wi-fi

#!/usr/bin/env python

from threading import Thread

from subprocess import Popen, PIPE, STDOUT import select, socket

import SocketServer HOST = '' PORT = 53515 IP = '192.168.43.142' bufferSize = 1024 meta_data = '{"port":%d,"name":"PyReceiver @ %s","id":"%s","width":1280,"height":960,"mirror":"h264","audio":" pcm","subtitles":"text/vtt","proxyHeaders":true,"hls":false,"upse ll":true}' % (PORT, IP, IP)

SAVE_TO_FILE = False class MyTCPHandler(SocketServer.BaseRequestHandler): def handle(self): if SAVE_TO_FILE: f = open('video.raw', 'wb') p = Popen(['ffplay', '-framerate', '30', '-'], stdin=PIPE, stdout=PIPE) #p = Popen(['gst-launch-1.0', 'fdsrc', '!', 'h264parse', '!', 'avdec_h264', '!', 'autovideosink'], stdin=PIPE,

stdout=PIPE)

skiped_metadata = False while True:

data = self.request.recv(bufferSize) if data == None or len(data) <= 0: break

if not skiped_metadata:

print "Client connected, addr: ", self.client_address[0]

if data.find('\r\n\r\n') > 0:

last_ctrl = data.find('\r\n\r\n') + 4 print 'Recv control data: ',

data[0:last_ctrl] if len(data) > last_ctrl: p.stdin.write(data[last_ctrl:]) if SAVE_TO_FILE: f.write(data[last_ctrl:]) skiped_metadata = True else:

(11)

31

Universitas Kristen Petra

p.stdin.write(data) if SAVE_TO_FILE: f.write(data) p.kill() if SAVE_TO_FILE: f.close() def resp_hello(ip, port):

send_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) send_sock.sendto(meta_data, (ip, port))

def handle_discovery(): s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.bind(('', PORT)) s.setblocking(0) while True: result = select.select([s],[],[]) if len(result[0]) <= 0: continue msg, address = result[0][0].recvfrom(bufferSize) print 'Receive broadcast msg: ', msg

if msg == 'hello':

print 'Got discover msg, src ip: %s, port: %d' % (address[0], address[1])

resp_hello(address[0], address[1])

if __name__ == "__main__":

server = SocketServer.TCPServer((HOST, PORT), MyTCPHandler) server_thread = Thread(target=server.serve_forever)

server_thread.daemon = True server_thread.start()

handle_discovery() server.shutdown()

(12)

4.4.2.

Menghubungkan Raspberry Pi Dengan smartphone Melalui Micro

USB

Source

code untuk

connect

ke aplikasi android melalui

Micro USB.

Source code

untuk menghubungkan Raspberry Pi dengan

smartphone

melalui

micro USB ada pada Segmen Program 4.17.

Source Code Raspberry Pi ke Android Melalui USB

#!/usr/bin/env python

from subprocess import Popen, PIPE, STDOUT import socket

PORT = 53516 bufferSize = 1024 SAVE_TO_FILE = False def connect_to_server():

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_address = ('localhost', PORT)

print 'Connecting to %s port %s' % server_address sock.connect(server_address)

try:

# Send data

message = 'mirror\n'

print 'Sending mirror cmd' sock.sendall(message) if SAVE_TO_FILE: f = open('video_client.raw', 'wb') p = Popen(['ffplay', '-framerate', '30', '-'], stdin=PIPE, stdout=PIPE) #p = Popen(['gst-launch-1.0', 'fdsrc', '!', 'h264parse', '!', 'avdec_h264', '!', 'autovideosink'], stdin=PIPE, stdout=PIPE)

skiped_metadata = False while True:

data = sock.recv(bufferSize)

if data == None or len(data) <= 0: break

if not skiped_metadata:

if data.find('\r\n\r\n') > 0:

last_ctrl = data.find('\r\n\r\n') + 4

print 'Recv control data: ', data[0:last_ctrl] if len(data) > last_ctrl: p.stdin.write(data[last_ctrl:]) if SAVE_TO_FILE: f.write(data[last_ctrl:]) skiped_metadata = True else: p.stdin.write(data) if SAVE_TO_FILE: f.write(data) p.kill()

(13)

33

Universitas Kristen Petra

if SAVE_TO_FILE: f.close() finally: sock.close() if __name__ == "__main__": connect_to_server()

Referensi

Dokumen terkait

RANCANG BANGUN APLIKASI ANDROID SEBAGAI PENAMPIL HASIL GAMBAR DARI RASPBERRY PI PADA PENDETEKSI KEHADIRAN TAMU BERBASIS WEB. (2015 : xiv + 60 Halaman + Daftar Gambar

Dari penelitian yang sudah dilakukan bahwa keamanan rumah berbasis android ini dapat disimpulkan (1) Sistem keamanan rumah telah berhasil dibuat dengan Raspberry

Komunikasi antara server dengan Raspberry pi dan server dengan aplikasi menunjukkan format data yang dipakai valid dan konsisten, hal ini ditunjukkan saat slot

1) Pemrograman kerja sensor, terutama BME280 pada Smart Mirror berbasis Raspberry Pi 4 menggunakan Bahasa Python. 2) Pemrograman sensor BME280 dapat menggunakan

Dari hasil perancangan hasil pengujian tersebut dapat diambil kesimpulan sebagai berikut : Sistem pada Raspberry Pi bisa memanfaatkan aplikasi aplikasi yang tersedia pada debian

Pada Gambar 3 di atas dapat dilihat gambaran umum sistem dari aplikasi navigasi.Pada gambar ini menjelaskan bahwa Raspberry Pi dapat difungsikan sebagai

Event Update module adalah query yang digunakan untuk mengubah status user menjadi fail jika belum menyelesaikan course pada waktu tertentu. Source code terhadap Event

Daftar Fitur, File Controller, Data Flow Diagram, dan Segmen Program Proses DFD Menu File Segmen Program Keterangan Proses 1.5 Pembelian ke supplier pembelian_insert1.php