โชว์วิดีโอใน VideoView จากการอัดวิดีโอจากกล้อง (Camera) และเลือกจากคลังวิดีโอ (Video Gallery)
สวัสดีครับ วันนี้ผมจะมาเขียนเกี่ยวกับการโชว์วิดีโอออกมาแสดงใน VideoView นะครับ ซึ่งบางท่านที่ยังไม่เคยใช้ฟังก์ชั่นตัวนี้ก็อาจจะงง ว่ามันคืออะไร VideoView คือ Widget ตัวนึงที่อยู่ในแอนดรอยด์ ทำหน้าที่ในการแสดงวิดีโอ คล้ายๆกับ ImageView นั้นแหละ โดยที่จะแสดงวิดีโอออกมาจะมาจากการอัดวิดีโอผ่านทางกล้องมือถือ และจากการเลือกวิดีโอในคลังวิดีโอ (Video Gallery) ซึ่งถ้าเอาจริงๆ ถามว่ามีฟังก์ชั่นที่ใช้แสดงวิดีโอนอกเหนือจากนี้ไหมก็จะมีเป็น ExoPlayer อีกตัวนึง ซึ่งตัวนี้ดีมากๆ และถูกรับรองโดยกูเกิล (Google) เรียบร้อย แต่ว่าในการเขียนโค้ด (Code) ก็เยอะขึ้นด้วยเช่นกัน
เอาล่ะจะช้าอยู่ไย ไปดูกันเลยยยยย
เวอร์ชั่นแอนดรอยด์ที่ใช้
- Phone : Sony Xperia XZ (มือถือของผมเอง)
- compileSdkVersion 26
- minSdkVersion 16
- targetSdkVersion 26
- versionCode 1
ทำความเข้าใจโค้ดก่อน
ก่อนจะเข้าไปดูโค้ด (Source Code) มาดูคำอธิบายการทำงานของโค้ดในแต่ละส่วนกันก่อนImageView imageView; VideoView vdoView; private Uri uri; static final int REQUEST_VIDEO_CAPTURE = 1; static final int REQUEST_TAKE_GALLERY_VIDEO = 2; String pathToStoredVideo;
ก่อนอื่นให้ประกาศตัวแปรในคำสั่งต่างๆ ของตัว Widget ที่ใช้ในการทำงานก่อน ซึ่งก็จะมี ImageView , VideoView , Uri , String และก็ Int 2 ตัวที่ใช้งานการกำหนดตัวไฟล์รูปมาจากการกล้อง (Camera) หรือเลือกจากคลังวิดีโอ (Gallery)
vdoView = (VideoView) findViewById(R.id.vdoView);
imageView = (ImageView) findViewById(R.id.imageView);
ต่อมาก็ประกาศ VideoView และ ImageView ซึ่งจริงๆ ImageView ในตัวอย่างนี้ผมเอามาไว้ซ้อนหน้า Video เท่านั้นครับ มันก็คือไอหน้ารูปสามเหลี่ยมปุ่ม Play นั้นแหละ ซึ่งถ้าใครที่เข้าใจแล้ว ก็ไม่ต้องใน ImageView ก็ได้นะครับ
final Button btnRecorder = (Button) findViewById(R.id.btnRecorder); btnRecorder.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { CharSequence[] items = {"ถ่ายวิดีโอ", "เลือกวิดีโอ"}; AlertDialog.Builder dialog = new AlertDialog.Builder(MainActivity.this); dialog.setTitle("กรุณาเลือกคำสั่ง"); dialog.setIcon(R.mipmap.ic_launcher_round); dialog.setItems(items, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int item) { if (item == 0) { Intent takeVideoIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE); if (takeVideoIntent.resolveActivity(getPackageManager()) != null) { takeVideoIntent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1); startActivityForResult(takeVideoIntent, REQUEST_VIDEO_CAPTURE); } } else { Intent intent = new Intent(); intent.setType("video/*"); intent.setAction(Intent.ACTION_GET_CONTENT); startActivityForResult(Intent.createChooser(intent,"Select Video"),REQUEST_TAKE_GALLERY_VIDEO); } } }); dialog.show(); } });
โค้ดเริ่มยาวขึ้นล่ะ ฮ่าๆๆ ต่อไปผมได้ทำการประกาศ Button หรือปุ่มกดอัดวิดีโอนั้นเอง โดยในเงื่อนไหนให้แสดง AlertDialog ออกมาว่าผู้ใช้นั้นสามารถเลือกได้ว่าจะอัดวิดีโอหรือว่าจะเลือกวิดีโอจากคลัง (Gallery)ได้ครับ โดยตรงฟังก์ชั่น Intent ที่เป็นการเปลี่ยนหน้าไปหน้าอื่นนั้น ถ้าสังเกตดีๆจะเห็น REQUEST_VIDEO_CAPTURE และ REQUEST_TAKE_GALLERY_VIDEO ซึ่งเป็น Int 2 ที่จะเป็นตัวที่ชี้ว่าเวลา Intent ไปยังฟังก์ชั่นไหนแล้ว ให้ส่งค่ากลับมายังไง โดยที่ในเงื่อนไข if (item == 0) นั้นจะเลือกไปที่กล้องเพื่ออัดวิดีโอ แล้วส่งวิดีโอกลับมายัง VideoView ส่วนเงื่อนไขที่ 2 else นั้นเป็นการเลือกไฟล์วิดีโอจากในคลัง (Video Gallery) แล้วส่งไฟล์นั้นกลับมายัง VideoView อีกเช่นเคย ดูต่อไป
final Button btnPlay = (Button) findViewById(R.id.btnPlay); btnPlay.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { vdoView.setVideoURI(uri); vdoView.setMediaController(new MediaController(MainActivity.this)); vdoView.requestFocus(); vdoView.start(); vdoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { public void onPrepared(MediaPlayer mp) { imageView.setVisibility(View.GONE); } }); } });
ต่อมาเป็นปุ่ม btnPlay นะครับหรือว่าปุ่มเล่นวิดีโอนั้นเอง โดยในเงื่อนไงนี้กำหนดไว้ว่า vdoView.setVideoURI(uri); กำหนด uri ที่เป็นค่าข้อมูลวิดีโอนั้นมาใส่ setMediaController เพื่อให้วิดีโอนั้นมีฟังก์ชั่นการเล่นวิดีโอได้เช่น การเลื่อนไปหน้าหลัง กดหยุด เป็นต้น แล้ว start(); ให้วิดีโอนั้นเล่นได้เลย สว่นในฟังก์ชัน setOnPreparedListener ก็คือเมื่อวิดีโอเล่นให้รูปภาพ ImageView นั้นหายไป
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if(resultCode == Activity.RESULT_OK && requestCode == REQUEST_VIDEO_CAPTURE){ uri = data.getData(); vdoView.setVideoURI(uri); pathToStoredVideo = getRealPathFromURIPath(uri, MainActivity.this); Log.i("Test" , pathToStoredVideo); } else if (requestCode == REQUEST_TAKE_GALLERY_VIDEO && resultCode == RESULT_OK) { uri = data.getData(); vdoView.setVideoURI(uri); pathToStoredVideo = getRealPathFromURIPath(uri, MainActivity.this); Log.i("Test", pathToStoredVideo); } } private String getRealPathFromURIPath(Uri uri, MainActivity mainActivity) { String generatedFilename = String.valueOf(System.currentTimeMillis()); String filePathEnvironment = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath(); File directoryFolder = new File(filePathEnvironment + "/video/"); if(!directoryFolder.exists()){ directoryFolder.mkdir(); } return filePathEnvironment + "/video/" + generatedFilename + ".mp4"; }
ต่อมาเป็นส่วนของ onActivityResult ครับ ส่วนนี้แหละสำคัญ เพราะส่วนนี้เป็นส่วนที่รับค่ามาจาก Intent ก่อนหน้านี้นั้นเอง จากนั้นก็วางเงื่อนไข if else ไว้ โดยที่ใน if ด้านบนจะเป็นรับค่ามาจากการอัดวิดีโอ และในส่วนของ else if รับค่ามาจากการเลือกไฟล์วิดีโอ แล้วเราก็ทำการ setVideoURI เพื่อใส่ข้อมูลลงใน VideoView แล้วก็ด้านล่างก็ประกาศ getRealPathFromURIPath ไว้ เพื่อเอาดึง Path วิดีโอนั้นๆออกมาได้ เอาไว้สำหรับนำไปประยุกงานต่อๆไป
vdoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { @Override public void onPrepared(MediaPlayer mp) { mp.setLooping(true); } });
แล้วก็ถ้าอยากให้วิดีโอเล่นไปเรื่อยๆ ไม่ต้องหยุดก็ใส่โค้ดนี้เข้าไปนะครับ วิดีโอเล่นจบมันก็จะเริ่มใหม่ แล้วก็เล่นต่อไปเรื่อยๆๆๆ แต่กินแบตน่าดู 555 จบไปดูโค้ดทั้งหมดเถอะ
โค้ดทั้งหมด
ไฟล์ XML : activity_main.xml<TableLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/tableLayout1" android:layout_width="fill_parent" android:layout_height="fill_parent"> <TableRow android:id="@+id/tableRow1" android:layout_width="wrap_content" android:layout_height="wrap_content" > <TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" android:text="Camera Recorder Videos" android:layout_span="1" android:textAppearance="?android:attr/textAppearanceLarge" /> </TableRow> <View android:layout_height="1dip" android:background="#CCCCCC" /> <TableLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="0.1" android:orientation="horizontal" android:gravity="center"> <RelativeLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="0.1" android:gravity="center"> <VideoView android:id="@+id/vdoView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="0.64" /> <ImageView android:id="@+id/imageView" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" android:layout_alignEnd="@+id/vdoView" android:src="@mipmap/ic_play_video" android:layout_alignRight="@+id/vdoView" /> </RelativeLayout> <Button android:id="@+id/btnRecorder" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Camera Recorder" /> <Button android:id="@+id/btnPlay" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Play" /> </TableLayout> <View android:layout_height="1dip" android:background="#CCCCCC" /> </TableLayout>
อันนี้เอามาจาก Thaicreate นะครับ
ไฟล์ Java : MainActivity.java
import android.app.Activity; import android.content.DialogInterface; import android.content.Intent; import android.media.MediaPlayer; import android.net.Uri; import android.os.Environment; import android.os.StrictMode; import android.provider.MediaStore; import android.support.v7.app.AlertDialog; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.ImageView; import android.widget.MediaController; import android.widget.VideoView; import java.io.File; import java.text.SimpleDateFormat; import java.util.Date; import java.util.UUID; public class MainActivity extends AppCompatActivity { ImageView imageView; VideoView vdoView; private Uri uri; static final int REQUEST_VIDEO_CAPTURE = 1; static final int REQUEST_TAKE_GALLERY_VIDEO = 2; String pathToStoredVideo; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); if (android.os.Build.VERSION.SDK_INT > 9) { StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build(); StrictMode.setThreadPolicy(policy); } vdoView = (VideoView) findViewById(R.id.vdoView); imageView = (ImageView) findViewById(R.id.imageView); // *** Camera Recorder final Button btnRecorder = (Button) findViewById(R.id.btnRecorder); btnRecorder.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { CharSequence[] items = {"ถ่ายวิดีโอ", "เลือกวิดีโอ"}; AlertDialog.Builder dialog = new AlertDialog.Builder(MainActivity.this); dialog.setTitle("กรุณาเลือกคำสั่ง"); dialog.setIcon(R.mipmap.ic_launcher_round); dialog.setItems(items, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int item) { if (item == 0) { Intent takeVideoIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE); if (takeVideoIntent.resolveActivity(getPackageManager()) != null) { takeVideoIntent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1); startActivityForResult(takeVideoIntent, REQUEST_VIDEO_CAPTURE); } } else { Intent intent = new Intent(); intent.setType("video/*"); intent.setAction(Intent.ACTION_GET_CONTENT); startActivityForResult(Intent.createChooser(intent,"Select Video"),REQUEST_TAKE_GALLERY_VIDEO); } } }); dialog.show(); } }); final Button btnPlay = (Button) findViewById(R.id.btnPlay); btnPlay.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { vdoView.setVideoURI(uri); vdoView.setMediaController(new MediaController(MainActivity.this)); vdoView.requestFocus(); vdoView.start(); vdoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { public void onPrepared(MediaPlayer mp) { imageView.setVisibility(View.GONE); } }); } }); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if(resultCode == Activity.RESULT_OK && requestCode == REQUEST_VIDEO_CAPTURE){ uri = data.getData(); vdoView.setVideoURI(uri); pathToStoredVideo = getRealPathFromURIPath(uri, MainActivity.this); Log.i("Test" , pathToStoredVideo); } else if (requestCode == REQUEST_TAKE_GALLERY_VIDEO && resultCode == RESULT_OK) { uri = data.getData(); vdoView.setVideoURI(uri); pathToStoredVideo = getRealPathFromURIPath(uri, MainActivity.this); Log.i("Test", pathToStoredVideo); } } private String getRealPathFromURIPath(Uri uri, MainActivity mainActivity) { String generatedFilename = String.valueOf(System.currentTimeMillis()); String filePathEnvironment = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath(); File directoryFolder = new File(filePathEnvironment + "/video/"); if(!directoryFolder.exists()){ directoryFolder.mkdir(); } return filePathEnvironment + "/video/" + generatedFilename + ".mp4"; } }
ไฟล์โค้ด Java ทั้งหมด
เป็นยังไงกันบ้างครับ สำหรับตัวอย่างนี้ "โชว์วิดีโอใน VideoView จากการอัดวิดีโอจากกล้อง (Camera) และเลือกจากคลังวิดีโอ (Video Gallery)" ไม่ยากเลยใช่ไหมครับ ซึ่งจริงๆตัวอย่างนี้สามารถทำเอาไปประยุกต์ใช้งานได้เยอะนะครับ หลายงานเลยที่เกี่ยวกับวิดีโอ เด่วจะทำของรูปด้วยรอแปป แล้วก็ถ้าใครที่ยังทำไม่ได้มี Source Code ให้ดาวโหลดไปทำกันนะครับ
ความคิดเห็น