2016-04-20 41 views
3

如何將本地視頻URI /路徑/文件設置爲chromecast的MediaInfo.Builder()?此外,任何人都可以請幫我一個關於如何從Android存儲器本地加載圖像和視頻的代碼片段,並將其投射到谷歌瀏覽器中。 也讀過其他問題,但在那裏已經提到要在應用上創建本地服務器。如果真的需要這樣做,那麼如何實現這個?我使用https://github.com/googlecast/CastVideos-android上的代碼,但在那裏,視頻是從url中獲取並播放的。我想從本地存儲加載視頻,我也想顯示圖像。將本地存儲器中的視頻和圖像加載到Google ChromeCast中android

更新: 現在我創建了一個使用「NanoHttpD」的本地服務器,但無法獲取所選本地文件的URL。下面是我Acitivities代碼片段:

public class VideoBrowserFragment extends Fragment implements VideoListAdapter.ItemClickListener, 
     LoaderManager.LoaderCallbacks<List<MediaInfo>> { 

    private static final String TAG = "zz VideoBrowserFragment"; 
    private static final int REQUEST_TAKE_GALLERY_VIDEO = 123; 
    private static final String CATALOG_URL = 
      "http://commondatastorage.googleapis.com/gtv-videos-bucket/CastVideos/f.json"; 
    private RecyclerView mRecyclerView; 
    private VideoListAdapter mAdapter; 
    private View mEmptyView; 
    private View mLoadingView; 
    private VideoCastManager mCastManager; 
    private VideoCastConsumerImpl mCastConsumer; 
    private View btnLocalVideo; 
    LocalServer server; 
    String chosenExt = ""; 
    String localFileName = ""; 
    String localFilePath = ""; 
    String formatedIpAddress = ""; 
    Uri selectedImageUri; 

    public VideoBrowserFragment() { 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, 
          @Nullable Bundle savedInstanceState) { 
     Toast.makeText(getActivity(), "VideoBrowserFragment onCreateView", Toast.LENGTH_SHORT).show(); 
     Log.d(TAG, "VideoBrowserFragment onCreateView"); 
     return inflater.inflate(R.layout.video_browser_fragment, container, false); 
    } 

    @Override 
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { 
     super.onViewCreated(view, savedInstanceState); 

     Toast.makeText(getActivity(), "VideoBrowserFragment onViewCreated", Toast.LENGTH_SHORT).show(); 
     Log.d(TAG, "VideoBrowserFragment onViewCreated"); 

     mRecyclerView = (RecyclerView) getView().findViewById(R.id.list); 
     mEmptyView = getView().findViewById(R.id.empty_view); 
     mLoadingView = getView().findViewById(R.id.progress_indicator); 
     btnLocalVideo = getView().findViewById(R.id.btnLocalVideo); 
     LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity()); 
     layoutManager.setOrientation(LinearLayoutManager.VERTICAL); 
     mRecyclerView.setLayoutManager(layoutManager); 
     mAdapter = new VideoListAdapter(this); 
     mRecyclerView.setAdapter(mAdapter); 
     getLoaderManager().initLoader(0, null, this); 
     mCastManager = VideoCastManager.getInstance(); 
     mCastConsumer = new VideoCastConsumerImpl() { 
      @Override 
      public void onConnected() { 
       super.onConnected(); 
       mAdapter.notifyDataSetChanged(); 
      } 

      @Override 
      public void onDisconnected() { 
       super.onDisconnected(); 
       mAdapter.notifyDataSetChanged(); 
      } 
     }; 
     mCastManager.addVideoCastConsumer(mCastConsumer); 


//fetch local video 
     btnLocalVideo.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 

       Intent intent = new Intent(); 
       intent.setType("video/*"); 
       intent.setAction(Intent.ACTION_GET_CONTENT); 
       startActivityForResult(Intent.createChooser(intent, "Select Video"), REQUEST_TAKE_GALLERY_VIDEO); 


      } 
     }); 
    } 


    //get data of locally fetched videos.... 
    @Override 
    public void onActivityResult(int requestCode, int resultCode, Intent data) { 
     if (resultCode == getActivity().RESULT_OK) { 
      if (requestCode == REQUEST_TAKE_GALLERY_VIDEO) { 
       selectedImageUri = data.getData(); 

       Toast.makeText(getActivity(), "Sending local video data", Toast.LENGTH_SHORT).show(); 
       MediaMetadata movieMetadata = new MediaMetadata(MediaMetadata.MEDIA_TYPE_MOVIE); 

       movieMetadata.putString(MediaMetadata.KEY_SUBTITLE, "Local Subtitle"); 
       movieMetadata.putString(MediaMetadata.KEY_TITLE, "Local Video is playing"); 

       JSONObject jsonObj = null; 
       try { 
        jsonObj = new JSONObject(); 
        jsonObj.put("description", "Sample Descrioption over here"); 
       } catch (JSONException e) { 
        Log.e(TAG, "Failed to add description to the json object", e); 
       } 
       String filePath = getPath(selectedImageUri); 
       chosenExt = filePath.substring(filePath.lastIndexOf(".") + 1); 
       startLocalServer(); 
       String localUrl = formatedIpAddress + localFilePath; 
       Log.d(TAG, "MediaInfo urlLocal: " + localUrl); 
       MediaInfo item = new MediaInfo.Builder(localUrl) 
         .setStreamType(MediaInfo.STREAM_TYPE_BUFFERED) 
         .setContentType("video/mp4") 
         .setMetadata(movieMetadata) 
         .setStreamDuration(333 * 1000) 
         .build(); 
       Log.d(TAG, "VideoBrowserFragment itemClicked media :" + Utils.mediaInfoToBundle(item)); 

       Intent intent = new Intent(getActivity(), LocalPlayerActivity.class); 
       intent.putExtra("media", Utils.mediaInfoToBundle(item)); 
       intent.putExtra("shouldStart", false); 
       intent.putExtra("isLocal", true); 
       intent.putExtra("videoUri", selectedImageUri.toString()); 
       /* Pair<View, String> imagePair = Pair 
         .create((View) viewHolder.getImageView(), transitionName);*/ 
       ActivityOptionsCompat options = ActivityOptionsCompat 
         .makeSceneTransitionAnimation(getActivity()); 
       ActivityCompat.startActivity(getActivity(), intent, options.toBundle()); 

      } 
     } 
    } 


    //get path of video fetched... 
    public String getPath(Uri uri) { 
     Log.d(TAG, "uri is " + uri); 
     String[] proj = {MediaStore.Images.Media.DATA}; 
     CursorLoader loader = new CursorLoader(getActivity(), uri, proj, null, null, null); 
     Cursor cursor = loader.loadInBackground(); 
     int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); 
     cursor.moveToFirst(); 

     if (cursor.moveToFirst()) { 
      //int column_index1 = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);//Instead of "MediaStore.Images.Media.DATA" can be used "_data" 
      Uri filePathUri = Uri.parse(cursor.getString(column_index)); 
      String file_name = filePathUri.getLastPathSegment().toString(); 
      String file_path = filePathUri.getPath(); 
      localFileName = file_name; 
      localFilePath = file_path; 
      Toast.makeText(getActivity(), "File Name & PATH are:" + file_name + "\n" + file_path, Toast.LENGTH_LONG).show(); 
      Log.d("zz fileData: ", "fp: " + file_path + " :and: fn: " + file_name); 
     } 
     String result = cursor.getString(column_index); 
     cursor.close(); 
     return result; 
    } 

    @Override 
    public void onDetach() { 
     Toast.makeText(getActivity(), "VideoBrowserFragment onDetach", Toast.LENGTH_SHORT).show(); 
     Log.d(TAG, "VideoBrowserFragment onDetach"); 
     mCastManager.removeVideoCastConsumer(mCastConsumer); 
     super.onDetach(); 
    } 

    @Override 
    public void itemClicked(View view, MediaInfo item, int position) { 
     Toast.makeText(getActivity(), "VideoBrowserFragment itemClicked", Toast.LENGTH_SHORT).show(); 
     Log.d(TAG, "VideoBrowserFragment itemClicked"); 

     if (view instanceof ImageButton) { 
      Log.d(TAG, "menu was clicked"); 
      com.scriptlanes.cast2.utils.Utils.showQueuePopup(getActivity(), view, item); 
     } else { 
      String transitionName = getString(R.string.transition_image); 
      VideoListAdapter.ViewHolder viewHolder = 
        (VideoListAdapter.ViewHolder) mRecyclerView.findViewHolderForPosition(position); 
      Pair<View, String> imagePair = Pair 
        .create((View) viewHolder.getImageView(), transitionName); 
      ActivityOptionsCompat options = ActivityOptionsCompat 
        .makeSceneTransitionAnimation(getActivity(), imagePair); 

      Intent intent = new Intent(getActivity(), LocalPlayerActivity.class); 
      Log.d(TAG, "VideoBrowserFragment itemClicked media :" + Utils.mediaInfoToBundle(item)); 

      intent.putExtra("media", Utils.mediaInfoToBundle(item)); 
      intent.putExtra("shouldStart", false); 
      //isUrl=true, isLocal=false 
      intent.putExtra("isLocal", false); 
      ActivityCompat.startActivity(getActivity(), intent, options.toBundle()); 
     } 
    } 

    @Override 
    public Loader<List<MediaInfo>> onCreateLoader(int id, Bundle args) { 
     Toast.makeText(getActivity(), "VideoBrowserFragment onCreateLoader", Toast.LENGTH_SHORT).show(); 
     Log.d(TAG, "VideoBrowserFragment onCreateLoader"); 

     return new VideoItemLoader(getActivity(), CATALOG_URL); 
    } 

    @Override 
    public void onLoadFinished(Loader<List<MediaInfo>> loader, List<MediaInfo> data) { 
     Toast.makeText(getActivity(), "VideoBrowserFragment onLoadFinished", Toast.LENGTH_SHORT).show(); 
     Log.d(TAG, "VideoBrowserFragment onLoadFinished"); 
     mAdapter.setData(data); 
     mLoadingView.setVisibility(View.GONE); 
     mEmptyView.setVisibility(null == data || data.isEmpty() ? View.VISIBLE : View.GONE); 
    } 

    @Override 
    public void onLoaderReset(Loader<List<MediaInfo>> loader) { 
     Toast.makeText(getActivity(), "VideoBrowserFragment onLoaderReset", Toast.LENGTH_SHORT).show(); 
     Log.d(TAG, "VideoBrowserFragment onLoaderReset"); 
     mAdapter.setData(null); 
    } 



    /*temp code nanohttpd*/ 


    public class LocalServer extends NanoHTTPD { 

     private final Logger LOG = Logger.getLogger(LocalServer.class.getName()); 

     public void main(String[] args) { 
      ServerRunner.run(LocalServer.class); 
     } 
     public LocalServer() { 
      super(3000); 
      Log.d("zz nanaHttpd: ", "STARTED"); 

     } 

     @Override 
     public Response serve(String uri, Method method, Map<String, String> header, Map<String, String> parameters, Map<String, String> files) { 
      //String mediasend = getExtension(chosenFile); 

      Log.d("zz nanaHttpd: ", "uri: " + uri+" , method: "+method); 
      FileInputStream fis = null; 
      File file = new File(localFilePath); 
      Log.e("Creando imputStream", "Size: "); 
      try { 
       fis = new FileInputStream(file); 
      } catch (FileNotFoundException e) { 
       e.printStackTrace(); 
      } 

      return new NanoHTTPD.Response(Response.Status.OK, "video/mp4", fis); 
     } 

    } 

    private void startLocalServer() { 
     server = new LocalServer(); 
     try { 
      server.start(); 
     } catch (IOException ioe) { 
      Log.d("zz Httpd", "The server could not start."); 
     } 
     Log.d("zz Httpd", "Web server initialized."); 
     WifiManager wifiManager = (WifiManager) getActivity().getSystemService(Context.WIFI_SERVICE); 
     int ipAddress = wifiManager.getConnectionInfo().getIpAddress(); 
     Log.d("zz Httpd IP U: ", ipAddress + ""); 
     String formatedIpAddress1 = String.format("%d.%d.%d.%d", (ipAddress & 0xff), (ipAddress >> 8 & 0xff), 
       (ipAddress >> 16 & 0xff), (ipAddress >> 24 & 0xff)); 
     formatedIpAddress = "http://" + formatedIpAddress1 + ":" + server.getListeningPort(); 
     Log.d("zz Httpd IP: ", "Please access! " + formatedIpAddress); 


    } 

    @Override 
    public void onDestroy() { 
     super.onDestroy(); 
     //server.stop(); 
    } 
} 

回答

0

正如你在其他職位所看到的,你需要一個嵌入式Web服務器添加到您的應用程序,並公開在該Web服務器的本地內容。然後,您需要將這些本地內容的網址發送給您的Chromecast。有許多開源小型嵌入式http服務器,如果您不想構建自己的小型http服務器,可以使用這些嵌入式解決方案。

+0

感謝@Ali Naddaf .......雖然我試圖通過「NanoHttpD」創建本地服務器,但我沒有得到如何傳遞所選視頻/圖像的URL。我做了以下事情:(1)通過意圖打開一個畫廊選擇一個視頻文件,然後onActivityResult我得到了所選視頻的URI。之後,我到底需要做什麼? – pravin

+0

Ali Naddaf我已經更新了我的問題,爲您添加了我的整個acitvity代碼..請你能告訴我一種方法,通過「NanoHttpD」本地服務器獲取所選視頻文件的網址。 – pravin

相關問題