Android多媒体编程
多媒體概念
- 文字、圖片、音頻、視頻
計算機圖片大小的計算
圖片大小 = 圖片的總像素 * 每個像素占用的大小
- 單色圖:每個像素占用1/8個字節(jié)
- 16色圖:每個像素占用1/2個字節(jié)
- 256色圖:每個像素占用1個字節(jié)
- 24位圖:每個像素占用3個字節(jié)
加載大圖片到內(nèi)存
Android系統(tǒng)以ARGB表示每個像素,所以每個像素占用4個字節(jié),很容易內(nèi)存溢出
對圖片進行縮放
- 獲取屏幕寬高
- 獲取圖片寬高
- 圖片的寬高除以屏幕寬高,算出寬和高的縮放比例,取較大值作為圖片的縮放比例
- 按縮放比例加載圖片
在內(nèi)存中創(chuàng)建圖片的副本
直接加載的bitmap對象是只讀的,無法修改,要修改圖片只能在內(nèi)存中創(chuàng)建出一個一模一樣的bitmap副本,然后修改副本
//加載原圖Bitmap srcBm = BitmapFactory.decodeFile("sdcard/photo3.jpg");iv_src.setImageBitmap(srcBm);//創(chuàng)建與原圖大小一致的空白bitmapBitmap copyBm = Bitmap.createBitmap(srcBm.getWidth(), srcBm.getHeight(), srcBm.getConfig());//定義畫筆Paint paint = new Paint();//把紙鋪在畫版上Canvas canvas = new Canvas(copyBm);//把srcBm的內(nèi)容繪制在copyBm上canvas.drawBitmap(srcBm, new Matrix(), paint);iv_copy.setImageBitmap(copyBm);對圖片進行特效處理
- 首先定義一個矩陣對象
Matrix mt = new Matrix(); - 縮放效果
- 旋轉(zhuǎn)效果
- 平移
- 鏡面
- 倒影
畫畫板
在Android 中可以給View 控件設(shè)置觸摸事件監(jiān)聽,這些觸摸事件包括用戶點擊下去
(ACTION_DOWN),移動(ACTION_MOVE)和抬起(ACTION_UP)。隨手涂鴉就是給ImageView(所有的控件都是View 的子類,都具備觸摸監(jiān)聽功能)設(shè)置觸摸監(jiān)聽事件,然后在ImageView 控件上進行繪制線條操作。
當(dāng)用戶ACTION_DOWN 的時候獲取當(dāng)前的x 和y 坐標(biāo)作為要繪制線條的起始坐標(biāo),當(dāng)
ACTION_MOVE(該事件只要用戶在滑動就不斷的被調(diào)用)的時候不斷的獲取新的x 和y 坐標(biāo),將新的坐標(biāo)作為要繪制線條的結(jié)束坐標(biāo)就可以繪制一條直線,然后將結(jié)束坐標(biāo)再作為新線條的起始坐標(biāo),依次類推,就能繪制出無限多個小直線,這些直線最終看起來就像是曲線的效果了。
最后可以將繪制好的圖片保存到本地文件中。
記錄用戶觸摸事件的XY坐標(biāo),繪制直線。給ImageView設(shè)置觸摸偵聽,得到用戶的觸摸事件,并獲知用戶觸摸ImageView的坐標(biāo)
iv.setOnTouchListener(new OnTouchListener() {@Overridepublic boolean onTouch(View v, MotionEvent event) {// TODO Auto-generated method stubswitch (event.getAction()) {//觸摸屏幕case MotionEvent.ACTION_DOWN://得到觸摸屏幕時手指的坐標(biāo)startX = (int) event.getX();startY = (int) event.getY();break;//在屏幕上滑動case MotionEvent.ACTION_MOVE://用戶滑動手指,坐標(biāo)不斷的改變,獲取最新坐標(biāo)int newX = (int) event.getX();int newY = (int) event.getY();//用上次onTouch方法得到的坐標(biāo)和本次得到的坐標(biāo)繪制直線canvas.drawLine(startX, startY, newX, newY, paint);iv.setImageBitmap(copyBm);startX = newX;startY = newY;break;}return true;} });- 刷子效果,加粗畫筆
- 調(diào)色板,改變畫筆顏色
- 保存圖片至SD卡
- 系統(tǒng)每次收到SD卡就緒廣播時,都會去遍歷sd卡的所有文件和文件夾,把遍歷到的所有多媒體文件都在MediaStore數(shù)據(jù)庫保存一個索引,這個索引包含多媒體文件的文件名、路徑、大小
- 圖庫每次打開時,并不會去遍歷sd卡獲取圖片,而是通過內(nèi)容提供者從MediaStore數(shù)據(jù)庫中獲取圖片的信息,然后讀取該圖片
- 系統(tǒng)開機或者點擊加載sd卡按鈕時,系統(tǒng)會發(fā)送sd卡就緒廣播,我們也可以手動發(fā)送就緒廣播
案例4:畫畫板
public class MainActivity extends Activity {private ImageView iv;int startX;int startY;private Canvas canvas;private Paint paint;private Bitmap bmCopy;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//加載畫畫板的背景圖Bitmap bmSrc = BitmapFactory.decodeResource(getResources(), R.drawable.bg);bmCopy = Bitmap.createBitmap(bmSrc.getWidth(), bmSrc.getHeight(), bmSrc.getConfig());paint = new Paint();canvas = new Canvas(bmCopy);//繪制canvas.drawBitmap(bmSrc, new Matrix(), paint);iv = (ImageView) findViewById(R.id.iv);iv.setImageBitmap(bmCopy);//設(shè)置觸摸偵聽iv.setOnTouchListener(new OnTouchListener() {//觸摸屏幕時,觸摸事件產(chǎn)生時,此方法調(diào)用@Overridepublic boolean onTouch(View v, MotionEvent event) {int action = event.getAction();switch (action) {//用戶手指摸到屏幕case MotionEvent.ACTION_DOWN:startX = (int) event.getX();startY = (int) event.getY();break;//用戶手指正在滑動case MotionEvent.ACTION_MOVE:int x = (int) event.getX();int y = (int) event.getY();canvas.drawLine(startX, startY, x, y, paint);//每次繪制完畢之后,本次繪制的結(jié)束坐標(biāo)變成下一次繪制的初始坐標(biāo)startX = x;startY = y;iv.setImageBitmap(bmCopy);break;//用戶手指離開屏幕case MotionEvent.ACTION_UP:break;}//true:告訴系統(tǒng),這個觸摸事件由我來處理//false:告訴系統(tǒng),這個觸摸事件我不處理,這時系統(tǒng)會把觸摸事件傳遞給imageview的父節(jié)點return true;}});}public void red(View v){paint.setColor(Color.RED);}public void green(View v){paint.setColor(Color.GREEN);}public void brush(View v){paint.setStrokeWidth(7);}public void save(View v){File file = new File("sdcard/dazuo.png");FileOutputStream fos = null;try {fos = new FileOutputStream(file);} catch (FileNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();}bmCopy.compress(CompressFormat.PNG, 100, fos);//發(fā)送sd卡就緒廣播Intent intent = new Intent();intent.setAction(Intent.ACTION_MEDIA_MOUNTED);intent.setData(Uri.fromFile(Environment.getExternalStorageDirectory()));sendBroadcast(intent);} }撕衣服
把穿內(nèi)衣和穿外衣的照片重疊顯示,內(nèi)衣照在下面,用戶滑動屏幕時,觸摸的是外衣照,把手指經(jīng)過的像素都置為透明,內(nèi)衣照就顯示出來了
使用幀布局疊加2 個ImageView,每個ImageView 負責(zé)顯示一張圖片,一張圖片有衣服,一張圖片沒有衣服,沒有衣服的圖片放置在下面,有衣服的圖片放置在上面。給上面的ImageView 設(shè)置觸摸的事件,當(dāng)手指觸摸到圖片上時,將手指觸摸到的點周邊的圖片的像素點設(shè)置為透明的,這樣下面的圖片就一點一點顯示出來了,從而有一種“撕衣服”的感覺。
在編寫該案例的時候應(yīng)該注意的事項如下:
1、 觸摸事件onTouch 的返回值必須設(shè)置為true,否則觸摸的事件將不被處理
2、 使用BitmapFactory 的decodeResouces 方法得到的圖片是沒有透明度的,即圖片格式為RGB_565,所
以若想能夠修改透明度,需要使用Canvas 對象對圖片進行重繪,重新繪制的圖片格式采用ARGB。
3、 加載圖片時需要對其進行一下壓縮,防止圖片與控件大小不匹配,導(dǎo)致觸摸時點對不上,達不到觸
摸哪里就設(shè)置哪里的像素點透明的效果。
每次只設(shè)置一個像素點太慢,以觸摸的像素為圓心,半徑為5畫圓,圓內(nèi)的像素全部置為透明
for (int i = -5; i < 6; i++) {for (int j = -5; j < 6; j++) {if(Math.sqrt(i * i + j * j) <= 5)copyBm.setPixel(newX + i, newY + j, Color.TRANSPARENT);} }案例5:撕衣服
public class MainActivity extends Activity {private Bitmap bmCopy;private ImageView iv;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Bitmap bmSrc = BitmapFactory.decodeResource(getResources(), R.drawable.awaiyi);bmCopy = Bitmap.createBitmap(bmSrc.getWidth(), bmSrc.getHeight(), bmSrc.getConfig());Paint paint = new Paint();Canvas canvas = new Canvas(bmCopy);canvas.drawBitmap(bmSrc, new Matrix(), paint);iv = (ImageView) findViewById(R.id.iv);iv.setOnTouchListener(new OnTouchListener() {@Overridepublic boolean onTouch(View v, MotionEvent event) {switch (event.getAction()) {case MotionEvent.ACTION_MOVE:int x = (int) event.getX();int y = (int) event.getY();for(int i = -5; i <= 5; i++){for(int j = -5; j <= 5; j++){//把用戶劃過的坐標(biāo)置為透明色//改變指定的像素顏色if(Math.sqrt(i*i + j*j) <= 5){if(x + i < bmCopy.getWidth() && y + j < bmCopy.getHeight() && x + i >= 0 && y + j >= 0){bmCopy.setPixel(x + i, y + j, Color.TRANSPARENT);iv.setImageBitmap(bmCopy);}}}}break;}return true;}});} }音樂播放器
播放服務(wù)
- 播放音頻的代碼應(yīng)該運行在服務(wù)中,定義一個播放服務(wù)MusicService
- 服務(wù)里定義play、stop、pause、continuePlay等方法
- 把這幾個方法抽取成一個接口MusicInterface
- 定義一個中間人類,繼承Binder,實現(xiàn)MusicInterface
- 先start啟動MusicService,再bind
根據(jù)播放進度設(shè)置進度條
- 獲取當(dāng)前的播放時間和當(dāng)前音頻的最長時間
- 播放進度需要不停的獲取,不停的刷新進度條,使用計時器每500毫秒獲取一次播放進度
- 發(fā)消息至Handler,把播放進度放進Message對象中,在Handler中更新SeekBar的進度
- 在Activity中定義Handler
拖動進度條改變播放進度
//給sb設(shè)置一個拖動偵聽sb.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {//停止拖動時調(diào)用@Overridepublic void onStopTrackingTouch(SeekBar seekBar) {// TODO Auto-generated method stubint progress = seekBar.getProgress();mi.seekTo(progress);}//開始拖動時調(diào)用 @Overridepublic void onStartTrackingTouch(SeekBar seekBar) {// TODO Auto-generated method stub}//拖動的時候不斷調(diào)用 @Overridepublic void onProgressChanged(SeekBar seekBar, int progress,boolean fromUser) {// TODO Auto-generated method stub} });視頻播放器
SurfaceView
- 對畫面的實時更新要求較高
- 雙緩沖技術(shù):內(nèi)存中有兩個畫布,A畫布顯示至屏幕,B畫布在內(nèi)存中繪制下一幀畫面,繪制完畢后B顯示至屏幕,A在內(nèi)存中繼續(xù)繪制下一幀畫面
- 播放視頻也是用MediaPlayer,不過跟音頻不同,要設(shè)置顯示在哪個SurfaceView
- SurfaceView是重量級組件,可見時才會創(chuàng)建
- 給SurfaceHolder設(shè)置CallBack,類似于偵聽,可以知道SurfaceView的狀態(tài)
- SurfaceView一旦不可見,就會被銷毀,一旦可見,就會被創(chuàng)建,銷毀時停止播放,再次創(chuàng)建時再開始播放
攝像頭
- 啟動系統(tǒng)提供的拍照程序
- 啟動系統(tǒng)提供的攝像程序
多媒體編程
- 文本、圖片、音頻、視頻
圖片
- 圖片在計算機中的大小
- 圖片的總大小 = 圖片的總像素 * 每個像素占用的大小
- 單色位圖:只能表示2種顏色
- 使用兩個數(shù)字:0和1
- 使用一個長度為1的二進制數(shù)字就可以表示了
- 每個像素占用1/8個字節(jié)
- 16色位圖:能表示16種顏色
- 需要16個數(shù)字:0-15,0000 - 1111
- 使用一個長度為4的二進制數(shù)組就可以表示了
- 每個像素占用1/2個字節(jié)
- 256色位圖:能表示256種顏色
- 需要256個數(shù)字:0 - 255,0000 0000 - 1111 1111
- 使用一個長度為8的二進制數(shù)字
- 每個像素占用1個字節(jié)
- 24位位圖:
- 每個像素占用24位,也就是3個字節(jié),所在叫24位位圖
- R:0-255,需要一個長度為8的二進制數(shù)字,占用1個字節(jié)
- G:0-255,需要一個長度為8的二進制數(shù)字,占用1個字節(jié)
- B:0-255,需要一個長度為8的二進制數(shù)字,占用1個字節(jié)
加載大圖片
- 計算機把圖片所有像素信息全部解析出來,保存至內(nèi)存
- Android保存圖片像素信息,是用ARGB保存
- 手機屏幕320*480,總像素:153600
- 圖片寬高2400*3200,總像素7680000
- 2400 / 320 = 7
- 3200 / 480 = 6
創(chuàng)建圖片副本
- 在內(nèi)存中創(chuàng)建一個圖片的拷貝
保存圖片
- SD每次準(zhǔn)備的時候,系統(tǒng)其實是遍歷sd卡所有文件,系統(tǒng)會把所有的多媒體文件,都在MediaStore數(shù)據(jù)庫中生成一個索引,數(shù)據(jù)庫中保存了文件的文件名、路徑、大小、長度和藝術(shù)家
- 圖庫、音樂、視頻程序每次啟動時,其實不會去遍歷sd卡尋找多媒體文件,而是直接從MediaStore數(shù)據(jù)庫中讀取多媒體文件,通過庫中的索引找到對應(yīng)的多媒體文件后,把文件顯示在界面
SurfaceView
- 雙緩沖技術(shù)
- 重量級組件
- 只要不可見,就不會創(chuàng)建,可見時,才會創(chuàng)建
- 只要不可見,就會銷毀
FFMPEG
- 開源免費的音視頻編解碼器
Vitamio
- 封裝了FFMPEG的視頻播放框架
- 對外提供的api全部都是javaApi
案例1:加載大圖片
public class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);}public void click(View v){//解析圖片時需要使用到的參數(shù)都封裝在這個對象里了Options opt = new Options();//不為像素申請內(nèi)存,只獲取圖片寬高opt.inJustDecodeBounds = true;BitmapFactory.decodeFile("sdcard/dog.jpg", opt);//拿到圖片寬高int imageWidth = opt.outWidth;int imageHeight = opt.outHeight;Display dp = getWindowManager().getDefaultDisplay();//拿到屏幕寬高int screenWidth = dp.getWidth();int screenHeight = dp.getHeight();//計算縮放比例int scale = 1;int scaleWidth = imageWidth / screenWidth;int scaleHeight = imageHeight / screenHeight;if(scaleWidth >= scaleHeight && scaleWidth >= 1){scale = scaleWidth;}else if(scaleWidth < scaleHeight && scaleHeight >= 1){scale = scaleHeight;}//設(shè)置縮放比例opt.inSampleSize = scale;opt.inJustDecodeBounds = false;Bitmap bm = BitmapFactory.decodeFile("sdcard/dog.jpg", opt);ImageView iv = (ImageView) findViewById(R.id.iv);iv.setImageBitmap(bm);}}案例2:創(chuàng)建圖片的副本
public class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//這個對象是只讀的Bitmap bmSrc = BitmapFactory.decodeFile("sdcard/photo3.jpg");//創(chuàng)建圖片副本//1.在內(nèi)存中創(chuàng)建一個與原圖一模一樣大小的bitmap對象,創(chuàng)建與原圖大小一致的白紙Bitmap bmCopy = Bitmap.createBitmap(bmSrc.getWidth(), bmSrc.getHeight(), bmSrc.getConfig());//2.創(chuàng)建畫筆對象Paint paint = new Paint();//3.創(chuàng)建畫板對象,把白紙鋪在畫板上Canvas canvas = new Canvas(bmCopy);//4.開始作畫,把原圖的內(nèi)容繪制在白紙上canvas.drawBitmap(bmSrc, new Matrix(), paint);ImageView iv_src = (ImageView) findViewById(R.id.iv_src);ImageView iv_copy = (ImageView) findViewById(R.id.iv_copy);iv_src.setImageBitmap(bmSrc);iv_copy.setImageBitmap(bmCopy);} }案例3:圖片的簡單特效
public class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//這個對象是只讀的Bitmap bmSrc = BitmapFactory.decodeFile("sdcard/photo3.jpg");//創(chuàng)建圖片副本//1.在內(nèi)存中創(chuàng)建一個與原圖一模一樣大小的bitmap對象,創(chuàng)建與原圖大小一致的白紙Bitmap bmCopy = Bitmap.createBitmap(bmSrc.getWidth(), bmSrc.getHeight(), bmSrc.getConfig());//2.創(chuàng)建畫筆對象Paint paint = new Paint();//3.創(chuàng)建畫板對象,把白紙鋪在畫板上Canvas canvas = new Canvas(bmCopy);//4.開始作畫,把原圖的內(nèi)容繪制在白紙上Matrix mt = new Matrix();//平移 // mt.setTranslate(20, 40);//縮放//sx:水平方向的縮放比例//sy:豎直方向的縮放比例 // mt.setScale(0.5f, 0.5f); // mt.setScale(0.5f, 0.5f, bmCopy.getWidth() / 2, bmCopy.getHeight() / 2);//旋轉(zhuǎn) // mt.setRotate(45, bmCopy.getWidth() / 2, bmCopy.getHeight() / 2);//鏡面 // mt.setScale(-1, 1); // mt.postTranslate(bmCopy.getWidth(), 0);//倒影mt.setScale(1, -1);mt.postTranslate(0, bmCopy.getHeight());canvas.drawBitmap(bmSrc, mt, paint);ImageView iv_src = (ImageView) findViewById(R.id.iv_src);ImageView iv_copy = (ImageView) findViewById(R.id.iv_copy);iv_src.setImageBitmap(bmSrc);iv_copy.setImageBitmap(bmCopy);} }案例6:播放音樂
package com.itheima.musicplayer;public interface MusicInterface {void play();void pause();void continuePlay();void seekTo(int progress); } public class MusicService extends Service {MediaPlayer player;private Timer timer;@Overridepublic IBinder onBind(Intent intent) {// TODO Auto-generated method stubreturn new MusicController();}class MusicController extends Binder implements MusicInterface{@Overridepublic void play() {MusicService.this.play();}@Overridepublic void pause() {MusicService.this.pause();}@Overridepublic void continuePlay() {MusicService.this.continuePlay();}@Overridepublic void seekTo(int progress) {MusicService.this.seekTo(progress);}}@Overridepublic void onCreate() {// TODO Auto-generated method stubsuper.onCreate();player = new MediaPlayer();}@Overridepublic void onDestroy() {// TODO Auto-generated method stubsuper.onDestroy();//停止播放player.stop();//釋放占用的資源,此時player對象已經(jīng)廢掉了player.release();player = null;if(timer != null){timer.cancel();timer = null;}}//播放音樂public void play(){//重置player.reset();try {//加載多媒體文件player.setDataSource("sdcard/zxmzf.mp3"); // player.setDataSource("http://192.168.13.119:8080/bzj.mp3"); // player.prepare();player.prepareAsync(); // player.start();player.setOnPreparedListener(new OnPreparedListener() {//準(zhǔn)備完畢時,此方法調(diào)用@Overridepublic void onPrepared(MediaPlayer mp) {player.start();addTimer();}});} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();} }//繼續(xù)播放public void continuePlay(){player.start();}//暫停播放public void pause(){player.pause();}public void seekTo(int progress){player.seekTo(progress);}public void addTimer(){if(timer == null){timer = new Timer();timer.schedule(new TimerTask() {@Overridepublic void run() {//獲取歌曲總時長int duration = player.getDuration();//獲取歌曲當(dāng)前播放進度int currentPosition= player.getCurrentPosition();Message msg = MainActivity.handler.obtainMessage();//把進度封裝至消息對象中Bundle bundle = new Bundle();bundle.putInt("duration", duration);bundle.putInt("currentPosition", currentPosition);msg.setData(bundle);MainActivity.handler.sendMessage(msg);}//開始計時任務(wù)后的5毫秒,第一次執(zhí)行run方法,以后每500毫秒執(zhí)行一次}, 5, 500);}} } public class MainActivity extends Activity {static Handler handler = new Handler(){public void handleMessage(android.os.Message msg) {Bundle bundle = msg.getData();int duration = bundle.getInt("duration");int currentPostition = bundle.getInt("currentPosition");//刷新進度條的進度sb.setMax(duration);sb.setProgress(currentPostition);}};MusicInterface mi;private MyserviceConn conn;private Intent intent;private static SeekBar sb;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);sb = (SeekBar) findViewById(R.id.sb);sb.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {@Overridepublic void onStopTrackingTouch(SeekBar seekBar) {//根據(jù)拖動的進度改變音樂播放進度int progress = seekBar.getProgress();//改變播放進度mi.seekTo(progress);}@Overridepublic void onStartTrackingTouch(SeekBar seekBar) {}@Overridepublic void onProgressChanged(SeekBar seekBar, int progress,boolean fromUser) {}});intent = new Intent(this, MusicService.class);startService(intent);conn = new MyserviceConn();bindService(intent, conn, BIND_AUTO_CREATE);}class MyserviceConn implements ServiceConnection{@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {mi = (MusicInterface) service;}@Overridepublic void onServiceDisconnected(ComponentName name) {// TODO Auto-generated method stub}}public void play(View v){mi.play();}public void continuePlay(View v){mi.continuePlay();}public void pause(View v){mi.pause();}public void exit(View v){unbindService(conn);stopService(intent);}}案例7:播放視頻
public class MainActivity extends Activity {private MediaPlayer player;static int currentPosition;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);SurfaceView sv = (SurfaceView) findViewById(R.id.sv);//拿到surfaceview的控制器final SurfaceHolder sh = sv.getHolder();// Thread t = new Thread(){ // @Override // public void run() { // // TODO Auto-generated method stub // try { // sleep(200); // } catch (InterruptedException e) { // // TODO Auto-generated catch block // e.printStackTrace(); // } // runOnUiThread(new Runnable() { // @Override // public void run() { // MediaPlayer player = new MediaPlayer(); // player.reset(); // try { // player.setDataSource("sdcard/2.3gp"); // player.setDisplay(sh); // player.prepare(); // player.start(); // } catch (Exception e) { // // TODO Auto-generated catch block // e.printStackTrace(); // } // // } // }); // // } // }; // t.start();sh.addCallback(new Callback() {//surfaceView銷毀時調(diào)用@Overridepublic void surfaceDestroyed(SurfaceHolder holder) {//每次surfaceview銷毀時,同時停止播放視頻if(player != null){currentPosition = player.getCurrentPosition();player.stop();player.release();player = null;}}//surfaceView創(chuàng)建時調(diào)用@Overridepublic void surfaceCreated(SurfaceHolder holder) {//每次surfaceView創(chuàng)建時才去播放視頻if(player == null){player = new MediaPlayer();player.reset();try {player.setDataSource("sdcard/2.3gp");player.setDisplay(sh);player.prepare();player.start();player.seekTo(currentPosition);} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();} }}//surfaceView結(jié)構(gòu)改變時調(diào)用@Overridepublic void surfaceChanged(SurfaceHolder holder, int format, int width,int height) {// TODO Auto-generated method stub}});}}案例8:VideoView
public class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//檢測是否支持vitamioif (!LibsChecker.checkVitamioLibs(this)) {return;}VideoView vv = (VideoView) findViewById(R.id.vv);vv.setVideoPath("sdcard/4.rmvb");vv.start();vv.setMediaController(new MediaController(this));} }案例9:攝像頭
public class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);}public void image(View v){//啟動系統(tǒng)提供的拍照activityIntent intent = new Intent();intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(Environment.getExternalStorageDirectory(), "haha.jpg")));startActivityForResult(intent, 10);}@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {// TODO Auto-generated method stubsuper.onActivityResult(requestCode, resultCode, data);if(requestCode == 10){Toast.makeText(this, "拍照成功", 0).show();}else if(requestCode == 20){Toast.makeText(this, "攝像成功", 0).show();}}public void video(View v){//啟動系統(tǒng)提供的攝像activityIntent intent = new Intent();intent.setAction(MediaStore.ACTION_VIDEO_CAPTURE);intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(Environment.getExternalStorageDirectory(), "haha.3gp")));intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);startActivityForResult(intent, 20);}}案例10:vitamio_lib
總結(jié)
以上是生活随笔為你收集整理的Android多媒体编程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android应用开发:页面跳转和数据传
- 下一篇: android sina oauth2.