2016-08-03 5 views
14

안드로이드에서 하나의 음악 응용 프로그램을 만들고 있습니다.이 음악 목록은 서버 측에서 오는 것입니다. 안드로이드에서 오디오 파형을 보여주는 법을 모르겠다. soundcloud 웹 사이트에서와 같이. 나는 아래 이미지를 첨부했다. enter image description here음성의 파형 표시

+1

안녕하세요 당신은 어떤 솔루션을 가지고 있나요 이 또한 나는 기록 애플 리케이션에서 동일한 문제에 붙어있다. 그것에 대해 아무거나 있으면 도움을주십시오. –

답변

6

아마도 오디오 샘플 만 시각화하고 싶다면 라이브러리없이이 기능을 구현할 수 있습니다. 예를 들어 : 코멘트 소량

public class PlayerVisualizerView extends View { 

    /** 
    * constant value for Height of the bar 
    */ 
    public static final int VISUALIZER_HEIGHT = 28; 

    /** 
    * bytes array converted from file. 
    */ 
    private byte[] bytes; 

    /** 
    * Percentage of audio sample scale 
    * Should updated dynamically while audioPlayer is played 
    */ 
    private float denseness; 

    /** 
    * Canvas painting for sample scale, filling played part of audio sample 
    */ 
    private Paint playedStatePainting = new Paint(); 
    /** 
    * Canvas painting for sample scale, filling not played part of audio sample 
    */ 
    private Paint notPlayedStatePainting = new Paint(); 

    private int width; 
    private int height; 

    public PlayerVisualizerView(Context context) { 
     super(context); 
     init(); 
    } 

    public PlayerVisualizerView(Context context, @Nullable AttributeSet attrs) { 
     super(context, attrs); 
     init(); 
    } 

    private void init() { 
     bytes = null; 

     playedStatePainting.setStrokeWidth(1f); 
     playedStatePainting.setAntiAlias(true); 
     playedStatePainting.setColor(ContextCompat.getColor(getContext(), R.color.gray)); 
     notPlayedStatePainting.setStrokeWidth(1f); 
     notPlayedStatePainting.setAntiAlias(true); 
     notPlayedStatePainting.setColor(ContextCompat.getColor(getContext(), R.color.colorAccent)); 
    } 

    /** 
    * update and redraw Visualizer view 
    */ 
    public void updateVisualizer(byte[] bytes) { 
     this.bytes = bytes; 
     invalidate(); 
    } 

    /** 
    * Update player percent. 0 - file not played, 1 - full played 
    * 
    * @param percent 
    */ 
    public void updatePlayerPercent(float percent) { 
     denseness = (int) Math.ceil(width * percent); 
     if (denseness < 0) { 
      denseness = 0; 
     } else if (denseness > width) { 
      denseness = width; 
     } 
     invalidate(); 
    } 

    @Override 
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) { 
     super.onLayout(changed, left, top, right, bottom); 
     width = getMeasuredWidth(); 
     height = getMeasuredHeight(); 
    } 

    @Override 
    protected void onDraw(Canvas canvas) { 
     super.onDraw(canvas); 
     if (bytes == null || width == 0) { 
      return; 
     } 
     float totalBarsCount = width/dp(3); 
     if (totalBarsCount <= 0.1f) { 
      return; 
     } 
     byte value; 
     int samplesCount = (bytes.length * 8/5); 
     float samplesPerBar = samplesCount/totalBarsCount; 
     float barCounter = 0; 
     int nextBarNum = 0; 

     int y = (height - dp(VISUALIZER_HEIGHT))/2; 
     int barNum = 0; 
     int lastBarNum; 
     int drawBarCount; 

     for (int a = 0; a < samplesCount; a++) { 
      if (a != nextBarNum) { 
       continue; 
      } 
      drawBarCount = 0; 
      lastBarNum = nextBarNum; 
      while (lastBarNum == nextBarNum) { 
       barCounter += samplesPerBar; 
       nextBarNum = (int) barCounter; 
       drawBarCount++; 
      } 

      int bitPointer = a * 5; 
      int byteNum = bitPointer/Byte.SIZE; 
      int byteBitOffset = bitPointer - byteNum * Byte.SIZE; 
      int currentByteCount = Byte.SIZE - byteBitOffset; 
      int nextByteRest = 5 - currentByteCount; 
      value = (byte) ((bytes[byteNum] >> byteBitOffset) & ((2 << (Math.min(5, currentByteCount) - 1)) - 1)); 
      if (nextByteRest > 0) { 
       value <<= nextByteRest; 
       value |= bytes[byteNum + 1] & ((2 << (nextByteRest - 1)) - 1); 
      } 

      for (int b = 0; b < drawBarCount; b++) { 
       int x = barNum * dp(3); 
       float left = x; 
       float top = y + dp(VISUALIZER_HEIGHT - Math.max(1, VISUALIZER_HEIGHT * value/31.0f)); 
       float right = x + dp(2); 
       float bottom = y + dp(VISUALIZER_HEIGHT); 
       if (x < denseness && x + dp(2) < denseness) { 
        canvas.drawRect(left, top, right, bottom, notPlayedStatePainting); 
       } else { 
        canvas.drawRect(left, top, right, bottom, playedStatePainting); 
        if (x < denseness) { 
         canvas.drawRect(left, top, right, bottom, notPlayedStatePainting); 
        } 
       } 
       barNum++; 
      } 
     } 
    } 

    public int dp(float value) { 
     if (value == 0) { 
      return 0; 
     } 
     return (int) Math.ceil(getContext().getResources().getDisplayMetrics().density * value); 
    } 
} 

죄송합니다, 코드,하지만 비주얼을 노력하고 있습니다. 원하는 모든 플레이어에 연결할 수 있습니다.

당신이 그것을 사용할 수있는 방법 : XML 레이아웃이보기를 추가, 당신은 방법 updateVisualizer에서

public void updateVisualizer(byte[] bytes) { 
    playerVisualizerView.updateVisualizer(bytes); 
} 

public void updatePlayerProgress(float percent) { 
    playerVisualizerView.updatePlayerPercent(percent); 
} 

당신이 오디오 샘플과 바이트 배열을 전달과 비주얼 상태를 업데이트 할 수 있고, 동적 updatePlayerProgress에서 당신 패스 백분율, 오디오 샘플 재생 중. 이 헬퍼 방법을 사용할 수 있습니다 바이트 파일을 변환

public static byte[] fileToBytes(File file) { 
    int size = (int) file.length(); 
    byte[] bytes = new byte[size]; 
    try { 
     BufferedInputStream buf = new BufferedInputStream(new FileInputStream(file)); 
     buf.read(bytes, 0, bytes.length); 
     buf.close(); 
    } catch (FileNotFoundException e) { 
     e.printStackTrace(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
    return bytes; 
} 

예 (아주 짧게)에 대한

, 그것은 모스 라이브러리처럼 보이는 방법 :

public class AudioRecorderPresenter extends MvpBasePresenter<AudioRecorderView> { 

public void onStopRecord() { 
     // stopped and released MediaPlayer 
     // ... 
     // some preparation and saved audio file in audioFileName variable. 

     getView().updateVisualizer(FileUtils.fileToBytes(new File(audioFileName))); 
     } 
    } 
} 
+1

Tanx, PlayerVisualizerView는 어떻게 사용할 수 있습니까? –

+1

최선의 답을주고 답을 +50으로 주셨을 것입니다. 그러나 자세한 내용을 추가하고 사용법을 보여주십시오. –

+0

@HamedGh이 (가) 업데이트되었습니다. 충분한가? – Scrobot