יום חמישי, נובמבר 4

נגן אודיו בסיסי


בפוסט זה נציג את פעולת ה-MediaPlayer ונבנה נגן אודיו בסיסי. ה-MediaPlayer הוא class הכולל גם אפשרות טיפול בוידאו. ראה קישור לאתר המפתחים של אנדרואיד.
הנגן מנגן שיר אחד בלבד, של הזמר ריי ווטסון.  שם השיר: All My Desires. אני מודה שהכרתי אותו רק בעקבות  חיפושי אחרי קבצי אודיו חופשיים להורדה חינם ובאופן חוקי.
הפורמט של השיר הוא mp3. גם midi, pcm ו -ogg vorbis נתמכים.
את הקובץ allmydesire.mp3 יש לשמור תחת  res/raw.
הנגן שלנו יכיל כפתור יחיד להפעלה והפסקת ההשמעה. הוא כולל תצוגה של אורך השיר. הוא יזהה את סיום השיר וידפיס הודעה על המסך.
הוספתי לתצוגה גם נתונים על השיר ותמונה של הזמר. התצוגה של הנגן נראית כך:




מעבר לשמירת קובץ המוסיקה תחת /res/raw ושמירת התמונה תחת res/draw, הקבצים שבהם נתעניין הם קובץ ה-layout ואובייקט הג'אווה היחיד.
ב-layout אין שום חידוש. מופיעים שם 3 סוגים של אלמנטים: Button, שלושה  TextView ו-ImageView. לא אציג את הקובץ כאן הפעם. הוא נמצא כמובן בחבילת הקבצים של הפרויקט הניתנת להורדה בהקלקה על הקישור.
שים לב, הקבצים הפעם בגודל 12MB, בגלל קבצי ה-mp3.

תוכן הקובץ הכולל את ה-class היחידי בפרויקט מוצג להלן.


  1. public class myAudioMediaPlayer extends Activity {
  2.     MediaPlayer mp;
  3.    
  4.     Button         playButton;
  5.     Button         stopButton;
  6.     Button         setMessageButton;
  7.     Button         clearMessageButton;
  8.     TextView    textBox;
  9.     TextView    textBox2;
  10.     TextView    textBox3;
  11.    
  12.     /** Called when the activity is first created. */
  13.     @Override
  14.     public void onCreate(Bundle savedInstanceState) {
  15.         super.onCreate(savedInstanceState);
  16.         setContentView(R.layout.main);
  17.         playButton = (Button)findViewById(R.id.play_button);
  18.         textBox       = (TextView)findViewById(R.id.text_box);
  19.         textBox2       = (TextView)findViewById(R.id.text_box2);
  20.         textBox3       = (TextView)findViewById(R.id.text_box3);
  21.          mp = MediaPlayer.create(this, R.raw.allmydesire);
  22.           String min = String.valueOf((mp.getDuration()/1000)/60);
  23.          String sec = String.valueOf((mp.getDuration()/1000)%60);
  24.          textBox2.setText( " All My Desire :"+"שם השיר");
  25.          textBox3.setText( " Ray Watson :"+"שם המבצע");
  26.          if(10> (mp.getDuration()/1000)%60)
  27.              textBox.setText(min +":0"+sec + " :"+"משך השיר");
  28.          else
  29.              textBox.setText(min +":"+sec + " :"+"משך השיר");
  30.          mp.setOnCompletionListener(new
  31.                  MediaPlayer.OnCompletionListener() {
  32.                  public void onCompletion(MediaPlayer mp)
  33.                  {
  34.                      mp.stop();
  35.                      textBox.setText("Song is Over. You can start again");
  36.                      playButton.setText("נגן");
  37.                      createMediaPlayerHelper();
  38.                  }
  39.                  });
  40.         
  41.         playButton.setOnClickListener(new View.OnClickListener() {
  42.             public void onClick(View view) {
  43.                 if(mp.isPlaying()){
  44.                     mp.pause();
  45.                     playButton.setText("נגן");
  46.                 }
  47.                 else{
  48.                     mp.start();
  49.                     playButton.setText("הפסק");
  50.                 }
  51.              }
  52.         });
  53.  
  54.     }
  55.     private void createMediaPlayerHelper(){
  56.         mp = MediaPlayer.create(this, R.raw.allmydesire);
  57.     }
  58. }

המתודה העיקרית היא onCreate ויש גם מתודת עזר בשם createMediaPlayerHelper
הסבר לinCreate :
חלק 1:
עד שורה 23, אלה בעיקר האיתחולים מהסוג הרגיל, של אלמנטי ה- UI.
חלק 2: יצירת האובייקט של ה- MediaPlayer עם (create(Context context, int resid, כשה-id לקוח מה-class R.java.
השורות 2 ו 3, מחשבות את אורך השיר בדקות ושניות על סמך המתודה getDuration.

  1. mp = MediaPlayer.create(this, R.raw.allmydesire)
  2. String min = String.valueOf((mp.getDuration()/1000)/60)
  3. String sec = String.valueOf((mp.getDuration()/1000)%60)
חלק 3: הצגה של הטקסט - SetText בעזרתו מדפיסים על המסך את פרטי השיר ואורכו.

  1.         textBox2.setText( " All My Desire :"+"שם השיר");
  2.          textBox3.setText( " Ray Watson :"+"שם המבצע");
  3.          if(10> (mp.getDuration()/1000)%60)
  4.              textBox.setText(min +":0"+sec + " :"+"משך השיר");
  5.          else
  6.              textBox.setText(min +":"+sec + " :"+"משך השיר");

חלק 4: callback  שיופעל עם סיום השיר. שימוש במתודה  setOnCompletionListener לרגיסטרציה של ה-callback. שהשיר נגמר עוצרים את הנגן (שורה 5), מדפיים הודעה ל-UI (שורה 6), הופכים את הכותרת שעל הכפתור מ"הפסק" ל"נגן", קוראים למתודת השירות (שורה 8), שיוצרת MediaPlayer מחדש. (הערה -יתכן שמספיק לעשות prepare - לבדוק)


  1.         mp.setOnCompletionListener(new
  2.                  MediaPlayer.OnCompletionListener() {
  3.                  public void onCompletion(MediaPlayer mp)
  4.                  {
  5.                      mp.stop();
  6.                      textBox.setText("Song is Over. You can start again");
  7.                      playButton.setText("נגן");
  8.                      createMediaPlayerHelper();
  9.                  }
  10.                  });
חלק 5: יצירת callback עבור כפתור השליטה בנגן.
עם הלחיצה על הכפתור מפעילים את המתודה pause (שורה 4) או start (שורה 8), לפי התוצאה של המתודה isPlaying- שורה 3. באותה ההזדמנות הופכים את הכיתוב על הכפתור מ-"נגן" ל- " הפסק" ולהפך (שורות 5 ו-9).

  1.        playButton.setOnClickListener(new View.OnClickListener() {
  2.             public void onClick(View view) {
  3.                 if(mp.isPlaying()){
  4.                     mp.pause();
  5.                     playButton.setText("נגן");
  6.                 }
  7.                 else{
  8.                     mp.start();
  9.                     playButton.setText("הפסק");
  10.                 }
  11.              }
  12.         });
בהחלט קצר ופשוט. עוד נחזור לתרגילים מורכבים יותר של ה-MediaPlayer.

4 תגובות:

  1. היי רונן,
    האם ניתן לעשות איזשהו עורך מדיה כדי לאפשר לחתוך שירים או וידאו בצורה קלה ? או אם יש לך הצעה ?
    תודה

    השבמחק
  2. תחפש שיטות שנותנות להעתיק ל-buffer מנק' מסויימת לנק' אחרת בקובץ ה-audio, אני יודע שיש את זה לקבצים רגילים של טקסט, אז בטוח שיש את זה לקבצי audio.
    ברגע שיש לך מקטע מסויים בחוצץ, אתה יכול לשחק איתו איך שבא לך, כמו למשל ליצור כמה חוצצים ולבצע עריכה כמו שרצית...

    השבמחק
  3. היי,
    נושא מעניין יכול להיות השימוש במחלקות MediaPlayer, MediaPlayerControl ו MediaController ליצירת נגן מדיה סטנדרטי, ולהבין את מערכת היחסים בניהם.
    שדרוג של זה יכול להיות כמובן הזרמת מדיה מהרשת (תוך כדי הורדת הקובץ), הצגת וידאו, והפעלת הנגן בservice על מנת לאפשר נגינה ברקע.

    השבמחק
  4. מאד מאד נהנתי מההסברים המפרטים "בעברית"!!!

    השבמחק