1. 程式人生 > >使用Jlayer和AudioTrack實現線上流媒體邊下邊播功能

使用Jlayer和AudioTrack實現線上流媒體邊下邊播功能

思路:通過http得到線上音訊檔案的輸入流,將未解碼的音訊流使用jlayer進行解碼操作,儲存解碼後的音訊資料到佇列中,通過另一執行緒讀取解碼後的音訊資料,從而邊下邊播的功能

/**
 * 解碼操作
 */
private class DecodeThread extends Thread {

        private InputStream inputStream = null;
        private URL url = null;
        private int sampleRate;
        private int channel;

        public
DecodeThread(URL url, int sampleRate, int channel) { this.url = url; this.sampleRate = sampleRate; this.channel = channel; } @Override public void run() { try { ByteArrayOutputStream outStream = new ByteArrayOutputStream(8
* 1024); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); inputStream = new BufferedInputStream(conn.getInputStream(), 8 * 1024); Bitstream bitstream = new Bitstream(inputStream); Decoder decoder = new Decoder(); boolean
done = false; SampleBuffer output; int frameIndex = 0; while (!done) { Header frameHeader = bitstream.readFrame(); if (frameHeader == null) { done = true; } else { output = (SampleBuffer) decoder.decodeFrame(frameHeader, bitstream); short[] pcm = output.getBuffer(); byte[] frameData = new byte[pcm.length]; for (int i = 0; i < pcm.length / 2; i++) { int j = i * 2; frameData[j] = (byte) (pcm[i] & 0xff); frameData[j + 1] = (byte) ((pcm[i] >> 8) & 0xff); } audioFrame.add(frameData); frameIndex++; } bitstream.closeFrame(); } //TODO 快取音訊資料 outStream.close(); } catch (IOException e) { e.printStackTrace(); } catch (BitstreamException e) { e.printStackTrace(); } catch (DecoderException e) { e.printStackTrace(); } } }
/**
 * 播放
 */
private class PlayThread extends Thread {
        @Override
        public void run() {
            mAudioTrack.play();
            int tempFrameIndex = 0;

            while (!isEnd) {
                if (!isPausing) {
                    handler.sendEmptyMessage(SimplePlayerHelper.STATE_PLAY);
                    try {
                        Thread.sleep(50);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                    List<byte[]> tempFrame = new ArrayList<byte[]>();
                    synchronized (audioFrame) {
                        tempFrame.addAll(audioFrame.subList(tempFrameIndex, tempFrameIndex > audioFrame.size() - 40 ? audioFrame.size() : tempFrameIndex + 40));
                    }

                    if (tempFrameIndex > 0 && tempFrame.isEmpty()) {
                        handler.sendEmptyMessage(SimplePlayerHelper.STATE_END);
                        isEnd = true;
                        onCompletionListener.onCompletion(mMyAudioTrack);
                    }
                    for (int i = 0; i < tempFrame.size(); i++) {
                        mAudioTrack.write(tempFrame.get(i), 0, tempFrame.get(i).length);
                    }
                    tempFrameIndex += tempFrame.size();
                }
            }
            audioFrame.clear();
            mAudioTrack.stop();
        }
    }

僅支援MP3流的線上播放功能,可使用其他音訊解碼庫實現多種音訊編碼格式的線上播放功能