當前位置: 首頁>>代碼示例>>Java>>正文


Java MediaCodecVideoTrackRenderer類代碼示例

本文整理匯總了Java中com.google.android.exoplayer.MediaCodecVideoTrackRenderer的典型用法代碼示例。如果您正苦於以下問題:Java MediaCodecVideoTrackRenderer類的具體用法?Java MediaCodecVideoTrackRenderer怎麽用?Java MediaCodecVideoTrackRenderer使用的例子?那麽, 這裏精選的類代碼示例或許可以為您提供幫助。


MediaCodecVideoTrackRenderer類屬於com.google.android.exoplayer包,在下文中一共展示了MediaCodecVideoTrackRenderer類的15個代碼示例,這些例子默認根據受歡迎程度排序。您可以為喜歡或者感覺有用的代碼點讚,您的評價將有助於係統推薦出更棒的Java代碼示例。

示例1: buildRenderers

import com.google.android.exoplayer.MediaCodecVideoTrackRenderer; //導入依賴的package包/類
@Override
public void buildRenderers(DemoPlayer player) {
  Allocator allocator = new DefaultAllocator(BUFFER_SEGMENT_SIZE);
  Handler mainHandler = player.getMainHandler();

  // Build the video and audio renderers.
  DefaultBandwidthMeter bandwidthMeter = new DefaultBandwidthMeter(mainHandler, null);
  DataSource dataSource = new DefaultUriDataSource(context, bandwidthMeter, userAgent);
  ExtractorSampleSource sampleSource = new ExtractorSampleSource(uri, dataSource, allocator,
      BUFFER_SEGMENT_COUNT * BUFFER_SEGMENT_SIZE, mainHandler, player, 0);
  MediaCodecVideoTrackRenderer videoRenderer = new MediaCodecVideoTrackRenderer(context,
      sampleSource, MediaCodecSelector.DEFAULT, MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT, 5000,
      mainHandler, player, 50);
  MediaCodecAudioTrackRenderer audioRenderer = new MediaCodecAudioTrackRenderer(sampleSource,
      MediaCodecSelector.DEFAULT, null, true, mainHandler, player,
      AudioCapabilities.getCapabilities(context), AudioManager.STREAM_MUSIC);
  TrackRenderer textRenderer = new TextTrackRenderer(sampleSource, player,
      mainHandler.getLooper());

  // Invoke the callback.
  TrackRenderer[] renderers = new TrackRenderer[DemoPlayer.RENDERER_COUNT];
  renderers[DemoPlayer.TYPE_VIDEO] = videoRenderer;
  renderers[DemoPlayer.TYPE_AUDIO] = audioRenderer;
  renderers[DemoPlayer.TYPE_TEXT] = textRenderer;
  player.onRenderers(renderers, bandwidthMeter);
}
 
開發者ID:Dreamxiaoxuan,項目名稱:AndroidTvDemo,代碼行數:27,代碼來源:ExtractorRendererBuilder.java

示例2: buildRenderers

import com.google.android.exoplayer.MediaCodecVideoTrackRenderer; //導入依賴的package包/類
@Override
public void buildRenderers(ExoPlayerHelper player) {
    Allocator allocator = new DefaultAllocator(BUFFER_SEGMENT_SIZE);

    // Build the video and audio renderers.
    Extractor webmExtractor = new WebmExtractor();
    Extractor mp4Extractor = new Mp4Extractor();
    DataSource dataSource = new FileDataSource();
    ExtractorSampleSource sampleSource = new ExtractorSampleSource(uri, dataSource, allocator,
            BUFFER_SEGMENT_COUNT * BUFFER_SEGMENT_SIZE, webmExtractor, mp4Extractor);
    MediaCodecVideoTrackRenderer videoRenderer = new MediaCodecVideoTrackRenderer(context,
            sampleSource, MediaCodecSelector.DEFAULT, MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT, 5000, player.getMainHandler(),
            player, 50);
    MediaCodecAudioTrackRenderer audioRenderer = new MediaCodecAudioTrackRenderer(sampleSource, MediaCodecSelector.DEFAULT,
            null, true, player.getMainHandler(), player);
    TrackRenderer textRenderer = new TextTrackRenderer(sampleSource, player,
            player.getMainHandler().getLooper());

    // Invoke the callback.
    TrackRenderer[] renderers = new TrackRenderer[ExoPlayerHelper.RENDERER_COUNT];
    renderers[ExoPlayerHelper.TYPE_VIDEO] = videoRenderer;
    renderers[ExoPlayerHelper.TYPE_AUDIO] = audioRenderer;
    renderers[ExoPlayerHelper.TYPE_TEXT] = textRenderer;
    player.onRenderers(renderers, null);
}
 
開發者ID:MimiReader,項目名稱:mimi-reader,代碼行數:26,代碼來源:WebmRendererBuilder.java

示例3: buildRenderers

import com.google.android.exoplayer.MediaCodecVideoTrackRenderer; //導入依賴的package包/類
@Override
public void buildRenderers(DemoPlayer player) {
  Allocator allocator = new DefaultAllocator(BUFFER_SEGMENT_SIZE);

  // Build the video and audio renderers.
  DefaultBandwidthMeter bandwidthMeter = new DefaultBandwidthMeter(player.getMainHandler(),
      null);
  DataSource dataSource = new DefaultUriDataSource(context, bandwidthMeter, userAgent);
  ExtractorSampleSource sampleSource = new ExtractorSampleSource(uri, dataSource, allocator,
      BUFFER_SEGMENT_COUNT * BUFFER_SEGMENT_SIZE);
  MediaCodecVideoTrackRenderer videoRenderer = new MediaCodecVideoTrackRenderer(context,
      sampleSource, MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT, 5000, player.getMainHandler(),
      player, 50);
  MediaCodecAudioTrackRenderer audioRenderer = new MediaCodecAudioTrackRenderer(sampleSource,
      null, true, player.getMainHandler(), player, AudioCapabilities.getCapabilities(context));
  TrackRenderer textRenderer = new TextTrackRenderer(sampleSource, player,
      player.getMainHandler().getLooper());

  // Invoke the callback.
  TrackRenderer[] renderers = new TrackRenderer[DemoPlayer.RENDERER_COUNT];
  renderers[DemoPlayer.TYPE_VIDEO] = videoRenderer;
  renderers[DemoPlayer.TYPE_AUDIO] = audioRenderer;
  renderers[DemoPlayer.TYPE_TEXT] = textRenderer;
  player.onRenderers(renderers, bandwidthMeter);
}
 
開發者ID:vuthanhict,項目名稱:ExoPlayerController,代碼行數:26,代碼來源:ExtractorRendererBuilder.java

示例4: pushSurface

import com.google.android.exoplayer.MediaCodecVideoTrackRenderer; //導入依賴的package包/類
private void pushSurface(boolean blockForSurfacePush) {
    Log.e(TAG, "pushSurface " + blockForSurfacePush);
    if (videoRenderer == null) {
        Log.e(TAG, "pushSurface (videoRenderer == null)");
        return;
    }
    if (surface == null) {
        Log.e(TAG, "pushSurface (surface == null)");
        return;
    }

    Log.e(TAG, "pushSurface " + blockForSurfacePush + " to " + videoRenderer);
    if (blockForSurfacePush) {
        player.blockingSendMessage(
                videoRenderer, MediaCodecVideoTrackRenderer.MSG_SET_SURFACE, surface);
    } else {
        player.sendMessage(
                videoRenderer, MediaCodecVideoTrackRenderer.MSG_SET_SURFACE, surface);
    }
}
 
開發者ID:quanhua92,項目名稱:GLMediaPlayer,代碼行數:21,代碼來源:CustomExoPlayer.java

示例5: buildRenderers

import com.google.android.exoplayer.MediaCodecVideoTrackRenderer; //導入依賴的package包/類
@Override
public void buildRenderers(MediaPlayer player) {
  Allocator allocator = new DefaultAllocator(BUFFER_SEGMENT_SIZE);

  // Build the video and audio renderers.
  DefaultBandwidthMeter bandwidthMeter = new DefaultBandwidthMeter(player.getMainHandler(),
      null);
  DataSource dataSource = new DefaultUriDataSource(context, bandwidthMeter, userAgent);
  ExtractorSampleSource sampleSource = new ExtractorSampleSource(uri, dataSource, allocator,
      BUFFER_SEGMENT_COUNT * BUFFER_SEGMENT_SIZE);
  MediaCodecVideoTrackRenderer videoRenderer = new MediaCodecVideoTrackRenderer(sampleSource,
      null, true, MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT, 5000, null, player.getMainHandler(),
      player, 50);
  MediaCodecAudioTrackRenderer audioRenderer = new MediaCodecAudioTrackRenderer(sampleSource,
      null, true, player.getMainHandler(), player);
  TrackRenderer textRenderer = new TextTrackRenderer(sampleSource, player,
      player.getMainHandler().getLooper());

  // Invoke the callback.
  TrackRenderer[] renderers = new TrackRenderer[MediaPlayer.RENDERER_COUNT];
  renderers[MediaPlayer.TYPE_VIDEO] = videoRenderer;
  renderers[MediaPlayer.TYPE_AUDIO] = audioRenderer;
  renderers[MediaPlayer.TYPE_TEXT] = textRenderer;
  player.onRenderers(null, null, renderers, bandwidthMeter);
}
 
開發者ID:XueyanLiu,項目名稱:miku,代碼行數:26,代碼來源:ExtractorRendererBuilder.java

示例6: buildRenderers

import com.google.android.exoplayer.MediaCodecVideoTrackRenderer; //導入依賴的package包/類
@Override
public void buildRenderers(Player player) {
  Allocator allocator = new DefaultAllocator(BUFFER_SEGMENT_SIZE);

  // Build the video and audio renderers.
  DefaultBandwidthMeter bandwidthMeter = new DefaultBandwidthMeter(player.getMainHandler(),
      null);
  DataSource dataSource = new DefaultUriDataSource(context, bandwidthMeter, userAgent);
  ExtractorSampleSource sampleSource = new ExtractorSampleSource(uri, dataSource, allocator,
      BUFFER_SEGMENT_COUNT * BUFFER_SEGMENT_SIZE);
  MediaCodecVideoTrackRenderer videoRenderer = new MediaCodecVideoTrackRenderer(context,
      sampleSource, MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT, 5000, player.getMainHandler(),
      player, 50);
  MediaCodecAudioTrackRenderer audioRenderer = new MediaCodecAudioTrackRenderer(sampleSource,
      null, true, player.getMainHandler(), player, AudioCapabilities.getCapabilities(context));
  TrackRenderer textRenderer = new TextTrackRenderer(sampleSource, player,
      player.getMainHandler().getLooper());

  // Invoke the callback.
  TrackRenderer[] renderers = new TrackRenderer[Player.RENDERER_COUNT];
  renderers[Player.TYPE_VIDEO] = videoRenderer;
  renderers[Player.TYPE_AUDIO] = audioRenderer;
  renderers[Player.TYPE_TEXT] = textRenderer;
  player.onRenderers(renderers, bandwidthMeter);
}
 
開發者ID:PJakcson,項目名稱:Mediathek,代碼行數:26,代碼來源:ExtractorRendererBuilder.java

示例7: prepareInternal

import com.google.android.exoplayer.MediaCodecVideoTrackRenderer; //導入依賴的package包/類
private void prepareInternal(boolean usingLocalMedia) {
        Log.d(TAG, "Prepare internal");
        try {
//            if(!usingLocalMedia) {
                mPlayer.prepare(audioRenderer, videoRenderer, textRenderer);
                mPlayer.sendMessage(audioRenderer, MediaCodecAudioTrackRenderer.MSG_SET_VOLUME,
                        mVolume);
                mPlayer.sendMessage(videoRenderer, MediaCodecVideoTrackRenderer.MSG_SET_SURFACE,
                        mSurface);
                // Disable text track by default.
                //mPlayer.setRendererEnabled(TvTrackInfo.TYPE_SUBTITLE, false);
//            }
            for (Callback callback : mCallbacks) {
                callback.onPrepared();
            }
        } catch(Exception E) {
            Log.e(TAG, E.getMessage() + "<(o.o<)");
            Log.e(TAG, E.getClass().getSimpleName());
            if(E.getClass().getName().contains("ExoPlaybackException")) {
                throw new IllegalArgumentException(E.getMessage()+"");
            }
        }
    }
 
開發者ID:Fleker,項目名稱:ChannelSurfer,代碼行數:24,代碼來源:TvInputPlayer.java

示例8: initRender

import com.google.android.exoplayer.MediaCodecVideoTrackRenderer; //導入依賴的package包/類
private void initRender(String url){
    Uri uri = Uri.parse(url);
    OkHttpDataSource okHttpDataSource = new OkHttpDataSource(RetrofitClient.getOkHttpClient(getContext())
            ,userAgent , null);
    okHttpDataSource.setRequestProperty("Referer", RetrofitClient.URL_REFERER);

    ExtractorSampleSource sampleSource = new ExtractorSampleSource(uri, okHttpDataSource, new DefaultAllocator(5 * K), 5 * K * K, new Mp4Extractor());


    mVideoRender = new MediaCodecVideoTrackRenderer(getContext()
            , sampleSource
            , MediaCodecSelector.DEFAULT
            , MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT);
    mAudioRender = new MediaCodecAudioTrackRenderer(sampleSource
            , MediaCodecSelector.DEFAULT);

    mPlayer.sendMessage(mVideoRender, MediaCodecVideoTrackRenderer.MSG_SET_SURFACE, mSurfaceView.getHolder().getSurface());
    mPlayer.setPlayWhenReady(true);
}
 
開發者ID:ayaseruri,項目名稱:luxunPro,代碼行數:20,代碼來源:VideoView.java

示例9: buildRenderers

import com.google.android.exoplayer.MediaCodecVideoTrackRenderer; //導入依賴的package包/類
public void buildRenderers(EMExoPlayer player) {
    //Create the Sample Source to be used by the renderers
    Allocator allocator = new DefaultAllocator(BUFFER_SEGMENT_SIZE);
    DefaultBandwidthMeter bandwidthMeter = new DefaultBandwidthMeter(player.getMainHandler(), player);
    DataSource dataSource = createDataSource(okHttpClient, null, userAgent);

    ExtractorSampleSource sampleSource = new ExtractorSampleSource(Uri.parse(MediaUtil.getUriWithProtocol(uri)), dataSource,
           allocator, BUFFER_SEGMENT_SIZE * BUFFER_SEGMENTS_TOTAL, player.getMainHandler(), player, 0);

    //Create the Renderers
    MediaCodecVideoTrackRenderer videoRenderer = new MediaCodecVideoTrackRenderer(context, sampleSource, MediaCodecSelector.DEFAULT,
            MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT, MAX_JOIN_TIME, player.getMainHandler(), player, DROPPED_FRAME_NOTIFICATION_AMOUNT);
    EMMediaCodecAudioTrackRenderer audioRenderer = new EMMediaCodecAudioTrackRenderer(sampleSource, MediaCodecSelector.DEFAULT, null, true,
            player.getMainHandler(), player, AudioCapabilities.getCapabilities(context), streamType);
    TrackRenderer captionsRenderer = new TextTrackRenderer(sampleSource, player, player.getMainHandler().getLooper());


    //Create the Render list to send to the callback
    TrackRenderer[] renderers = new TrackRenderer[EMExoPlayer.RENDER_COUNT];
    renderers[EMExoPlayer.RENDER_VIDEO] = videoRenderer;
    renderers[EMExoPlayer.RENDER_AUDIO] = audioRenderer;
    renderers[EMExoPlayer.RENDER_CLOSED_CAPTION] = captionsRenderer;
    player.onRenderers(renderers, bandwidthMeter);
}
 
開發者ID:ayaseruri,項目名稱:luxunPro,代碼行數:25,代碼來源:RenderBuilder.java

示例10: maybeStartPlayback

import com.google.android.exoplayer.MediaCodecVideoTrackRenderer; //導入依賴的package包/類
private void maybeStartPlayback() {
    Log.d(TAG, "maybeStartPlayback");
    Surface surface = surfaceView.getHolder().getSurface();
    if (videoRenderer == null || surface == null || !surface.isValid()) {
        // We're not ready yet.
        return;
    }
    player.sendMessage(videoRenderer, MediaCodecVideoTrackRenderer.MSG_SET_SURFACE, surface);
    if (autoPlay) {
        if (mIsOnTv) {
            // This will update the player controls and the activity will receive the callback
            // OnPlayPauseClickedListener.onFragmentPlayPause(Video, int, Boolean)
            mPlaybackOverlayFragment.pressPlay();
        } else {
            player.setPlayWhenReady(true);
        }
        autoPlay = false;
    }
}
 
開發者ID:googlecodelabs,項目名稱:android-tv-leanback,代碼行數:20,代碼來源:PlayerActivity.java

示例11: preparePlayer

import com.google.android.exoplayer.MediaCodecVideoTrackRenderer; //導入依賴的package包/類
private void preparePlayer() {

        SampleSource sampleSource =
                new FrameworkSampleSource(this, Uri.parse(mVideo.getContentUrl()), /* headers */ null, RENDERER_COUNT);

        // Build the track renderers
        videoRenderer = new MediaCodecVideoTrackRenderer(sampleSource, MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT);
        TrackRenderer audioRenderer = new MediaCodecAudioTrackRenderer(sampleSource);


        // Setup the player
        player = ExoPlayer.Factory.newInstance(RENDERER_COUNT, 1000, 5000);
        player.addListener(this);
        // Build the player controls
        mediaController.setMediaPlayer(new PlayerControl(player));
        mediaController.setEnabled(true);
        player.prepare(videoRenderer, audioRenderer);
    }
 
開發者ID:googlecodelabs,項目名稱:android-tv-leanback,代碼行數:19,代碼來源:PlayerActivity.java

示例12: preparePlayer

import com.google.android.exoplayer.MediaCodecVideoTrackRenderer; //導入依賴的package包/類
private void preparePlayer() {

        SampleSource sampleSource =
                new FrameworkSampleSource(this, Uri.parse(mVideo.getContentUrl()), /* headers */ null, RENDERER_COUNT);

        // Build the track renderers
        videoRenderer = new MediaCodecVideoTrackRenderer(sampleSource, MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT);
        TrackRenderer audioRenderer = new MediaCodecAudioTrackRenderer(sampleSource);

        // Setup the player
        player = ExoPlayer.Factory.newInstance(RENDERER_COUNT, 1000, 5000);
        player.addListener(this);
        // Build the player controls
        mediaController.setMediaPlayer(new PlayerControl(player));
        mediaController.setEnabled(true);
        player.prepare(videoRenderer, audioRenderer);
    }
 
開發者ID:googlecodelabs,項目名稱:android-tv-leanback,代碼行數:18,代碼來源:PlayerActivity.java

示例13: buildRenderers

import com.google.android.exoplayer.MediaCodecVideoTrackRenderer; //導入依賴的package包/類
@Override
protected void buildRenderers(RendererBuilderCallback callback) {
    Allocator allocator = new DefaultAllocator(bufferSegmentSize);
    DataSource dataSource = new DefaultUriDataSource(context, bandwidthMeter, userAgent);
    ExtractorSampleSource sampleSource = new ExtractorSampleSource(uri, dataSource,
            allocator, bufferSegmentSize * bufferSegmentCount);
    MediaCodecVideoTrackRenderer videoRenderer = new MediaCodecVideoTrackRenderer(context,
            sampleSource, MediaCodecSelector.DEFAULT,
            MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT, 5000,
            eventHandler, eventProxy, 50);
    MediaCodecAudioTrackRenderer audioRenderer = new MediaCodecAudioTrackRenderer(sampleSource,
            MediaCodecSelector.DEFAULT, null, true, eventHandler, eventProxy,
            AudioCapabilities.getCapabilities(context), AudioManager.STREAM_MUSIC);

    TrackRenderer textRenderer = new TextTrackRenderer(sampleSource, eventProxy,
            eventHandler.getLooper());

    // Invoke the callback.
    TrackRenderer[] renderers = new TrackRenderer[Player.RENDERER_COUNT];
    renderers[Player.TYPE_VIDEO] = videoRenderer;
    renderers[Player.TYPE_AUDIO] = audioRenderer;
    renderers[Player.TYPE_TEXT] = textRenderer;
    callback.onRenderers(renderers, bandwidthMeter);
}
 
開發者ID:satorufujiwara,項目名稱:exoplayer-textureview,代碼行數:25,代碼來源:AssetsRendererBuilder.java

示例14: buildRenderers

import com.google.android.exoplayer.MediaCodecVideoTrackRenderer; //導入依賴的package包/類
@Override
public void buildRenderers(ExoPlayerWrapper player) {
    Allocator allocator = new DefaultAllocator(BUFFER_SEGMENT_SIZE);

    // Build the video and audio renderers.
    DefaultBandwidthMeter bandwidthMeter = new DefaultBandwidthMeter(player.getMainHandler(),
            null);
    DataSource dataSource = new DefaultUriDataSource(context, bandwidthMeter, userAgent);
    ExtractorSampleSource sampleSource = new ExtractorSampleSource(uri, dataSource, allocator,
            BUFFER_SEGMENT_COUNT * BUFFER_SEGMENT_SIZE);
    MediaCodecVideoTrackRenderer videoRenderer = new MediaCodecVideoTrackRenderer(context,
            sampleSource, MediaCodecSelector.DEFAULT, MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT, 5000,
            player.getMainHandler(), player, 50);
    MediaCodecAudioTrackRenderer audioRenderer = new MediaCodecAudioTrackRenderer(sampleSource,
            MediaCodecSelector.DEFAULT, null, true, player.getMainHandler(), player,
            AudioCapabilities.getCapabilities(context), AudioManager.STREAM_MUSIC);
    TrackRenderer textRenderer = new TextTrackRenderer(sampleSource, player,
            player.getMainHandler().getLooper());

    // Invoke the callback.
    TrackRenderer[] renderers = new TrackRenderer[ExoPlayerWrapper.RENDERER_COUNT];
    renderers[ExoPlayerWrapper.TYPE_VIDEO] = videoRenderer;
    renderers[ExoPlayerWrapper.TYPE_AUDIO] = audioRenderer;
    renderers[ExoPlayerWrapper.TYPE_TEXT] = textRenderer;
    player.onRenderers(renderers, bandwidthMeter);
}
 
開發者ID:cklar,項目名稱:ExoPlayerWrapper,代碼行數:27,代碼來源:ExtractorRendererBuilder.java

示例15: buildRenderers

import com.google.android.exoplayer.MediaCodecVideoTrackRenderer; //導入依賴的package包/類
@Override
public void buildRenderers(DemoPlayer player, RendererBuilderCallback callback) {
  // Build the video and audio renderers.
  FrameworkSampleSource sampleSource = new FrameworkSampleSource(context, uri, null, 2);
  MediaCodecVideoTrackRenderer videoRenderer = new MediaCodecVideoTrackRenderer(sampleSource,
      null, true, MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT, 5000, null, player.getMainHandler(),
      player, 50);
  MediaCodecAudioTrackRenderer audioRenderer = new MediaCodecAudioTrackRenderer(sampleSource,
      null, true, player.getMainHandler(), player);

  // Build the debug renderer.
  TrackRenderer debugRenderer = debugTextView != null
      ? new DebugTrackRenderer(debugTextView, videoRenderer)
      : null;

  // Invoke the callback.
  TrackRenderer[] renderers = new TrackRenderer[DemoPlayer.RENDERER_COUNT];
  renderers[DemoPlayer.TYPE_VIDEO] = videoRenderer;
  renderers[DemoPlayer.TYPE_AUDIO] = audioRenderer;
  renderers[DemoPlayer.TYPE_DEBUG] = debugRenderer;
  callback.onRenderers(null, null, renderers);
}
 
開發者ID:Weco,項目名稱:android-exoplayer,代碼行數:23,代碼來源:DefaultRendererBuilder.java


注:本文中的com.google.android.exoplayer.MediaCodecVideoTrackRenderer類示例由純淨天空整理自Github/MSDocs等開源代碼及文檔管理平台,相關代碼片段篩選自各路編程大神貢獻的開源項目,源碼版權歸原作者所有,傳播和使用請參考對應項目的License;未經允許,請勿轉載。