【问题标题】:Is uploading videos from an SD Card to Facebook possible with the Facebook SDK?是否可以使用 Facebook SDK 将视频从 SD 卡上传到 Facebook?
【发布时间】:2011-10-18 00:21:54
【问题描述】:

我们可以通过 Facebook SDK 将视频从 Android 设备的 SD 卡上传到 Facebook 帐户吗?

如果有,有哪些简单的例子?

【问题讨论】:

    标签: android facebook facebook-graph-api


    【解决方案1】:

    是的,这是可能的!经过两天的尝试和研究,我能够做到。 代码如下:

    byte[] data = null;
    String dataPath = "/mnt/sdcard/KaraokeVideos/myvideo.3gp";
    String dataMsg = "Your video description here.";
    Bundle param;
    facebook = new Facebook(FB_APP_ID);
    AsyncFacebookRunner mAsyncRunner = new AsyncFacebookRunner(facebook);
    InputStream is = null;
    try {
        is = new FileInputStream(dataPath);
        data = readBytes(is);
        param = new Bundle();
        param.putString("message", dataMsg);
        param.putString("filename", dataName);
        param.putByteArray("video", data);
        mAsyncRunner.request("me/videos", param, "POST", new fbRequestListener(), null);
    }
    catch (FileNotFoundException e) {
       e.printStackTrace();
    }
    catch (IOException e) {
       e.printStackTrace();
    }
    

    其中fbRequestListener()AsyncFacebookRunner.RequestListener() 的实现,readBytes() 是将视频文件转换为byte[] 的函数。 dataName 字符串应包含有效的文件扩展名(3gp、mp4 等)。代码如下:

    public byte[] readBytes(InputStream inputStream) throws IOException {
        // This dynamically extends to take the bytes you read.
        ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream();
    
        // This is storage overwritten on each iteration with bytes.
        int bufferSize = 1024;
        byte[] buffer = new byte[bufferSize];
    
        // We need to know how may bytes were read to write them to the byteBuffer.
        int len = 0;
        while ((len = inputStream.read(buffer)) != -1) {
            byteBuffer.write(buffer, 0, len);
        }
    
        // And then we can return your byte array.
        return byteBuffer.toByteArray();
    }
    

    我从这个answer得到这个功能。

    当然,您需要拥有最新的 Facebook SDK,但我们需要应用此 patch 来修复 {"error":{"type":"OAuthException","message":"(#352) Video file format is not supported"}} 字符串响应错误。

    就是这样!我希望这会有所帮助!

    【讨论】:

    • 您好,我使用了您发布的答案。它工作正常,但我有这个错误 {"error":{"type":"OAuthException","message":"(#352) Video file format is not supported"}}。你提供了最新的补丁来解决这个错误。所以请告诉我我必须更改 util 类中的代码
    • 我已编辑我的答案以包含视频文件名的附加参数。另外,需要在 Util 类中应用的补丁可以在这个链接中找到:patch_link
    • 嗨,埃里克!我被这个错误困住了。我试过你的答案。但它仍然没有为我做伟大的事情。我很困惑使用你的方式来实现补丁..无论如何..所以你可以为这个东西安排一个工作演示。这对所有人来说真的是一件好事。谢谢
    • 此代码有效,但在您发送容器为 mp4 的视频时无效(如果是 3gp 则有效)。它得到一个 moov atom not found 错误,显示在 ffmpeg 信息中。
    • @Erick 感谢上面的示例,它可以很好地在 Facebook 上上传小文件,但是当我尝试发布 95MB 的视频文件时,它会抛出 java.lang.OutOfMemoryError 错误,请您帮忙帮我解决这个问题。提前致谢。
    【解决方案2】:

    随着新的 facebook SDK 3.5 的发布,视频上传变得更加容易。 如果您使用的是 sdk 3.5 或更高版本,这里是上传视频到 facebook 的代码

    //Path to the video, Ex: path = Environment.getExternalStorageDirectory() + File.separator + "myVideo.mp4";
            String path;
            //get the current active facebook session
            Session session = Session.getActiveSession();
            //If the session is open
            if(session.isOpened()) {
                //Get the list of permissions associated with the session
                List<String> permissions = session.getPermissions();
                //if the session does not have video_upload permission
                if(!permissions.contains("video_upload")) {
                    //Get the permission from user to upload the video to facebook
                    Session.NewPermissionsRequest newPermissionsRequest = new Session
                            .NewPermissionsRequest(this, Arrays.asList("video_upload"));
                    session.requestNewReadPermissions(newPermissionsRequest);
                }
    
    
                //Create a new file for the video 
                File file = new File(path);
                try {
                    //create a new request to upload video to the facebook
                    Request videoRequest = Request.newUploadVideoRequest(session, file, new Request.Callback() {
    
                        @Override
                        public void onCompleted(Response response) {
    
                            if(response.getError()==null)
                            {
                                Toast.makeText(MainActivity.this, "video shared successfully", Toast.LENGTH_SHORT).show();
                            }
                            else
                            {
                                Toast.makeText(MainActivity.this, response.getError().getErrorMessage(), Toast.LENGTH_SHORT).show();
                            }
                        }
                    });
    
                    //Execute the request in a separate thread
                    videoRequest.executeAsync();
    
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                }
            }
    
            //Session is not open
            else {
                Toast.makeText(getApplicationContext(), "Please login to facebook first", Toast.LENGTH_SHORT).show();
            }
    

    【讨论】:

      【解决方案3】:

      修补Util文件后,没有得到结果。

      我遇到了softy提到的问题。

      我在 android 中尝试过这个...现在可以成功运行了.. 一段时间后(1 分钟内)我的墙上显示了视频..(可能是,facebook 正在刷新数据..)

      String path="\mnt\sdcard\test.mp4";
      
          if (new File(path).exists()) {
              try {
                  byte[] data = null;
                  String dataPath = new File(path).getAbsolutePath();
                  Log.e("", dataPath);
                  String dataMsg = "It is the short movie created";
                  Bundle param;
                  InputStream is = null;
                  try {
                      is = new FileInputStream(dataPath);
                      data = readBytes(is);
                      param = new Bundle();
                      // param.putString("filename", "" + new
                      // File(path).getName());
                      // param.putString("mimeType", "video/mp4");
                      param.putString("message", dataMsg);
                      param.putString("title", "title");
                      param.putString("contentType", "video/quicktime");
                      param.putByteArray("video.mov", data);
                      Utility.mAsyncRunner.request("me/videos", param, "POST",
                              new FBRequestListener(), null);
      
                      Toast.makeText(getContext(), "Uploading...",
                              Toast.LENGTH_SHORT).show();
                  } catch (FileNotFoundException e) {
                      e.printStackTrace();
                  } catch (IOException e) {
                      e.printStackTrace();
                  }
              } catch (Exception e) {
                  e.printStackTrace();
              }
          } else {
              Toast.makeText(getContext(), "No videos found in these dates",
                      Toast.LENGTH_SHORT).show();
          }
      

      FBRequestListener.java

      public class FBRequestListener implements RequestListener {
      
          @Override
          public void onComplete(String response, Object state) {
              Log.e("response", response);
              // Log.e("state", state.toString());
          }
      
          @Override
          public void onIOException(IOException e, Object state) {
              Log.e("", "onIOException");
              e.printStackTrace();
      
          }
      
          @Override
          public void onFileNotFoundException(FileNotFoundException e,
                  Object state) {
              Log.e("", "onFileNotFoundException");
              e.printStackTrace();
      
          }
      
          @Override
          public void onMalformedURLException(MalformedURLException e,
                  Object state) {
              Log.e("", "onMalformedURLException");
              e.printStackTrace();
          }
      
          @Override
          public void onFacebookError(FacebookError e, Object state) {
              Log.e("", "onFacebookError");
              e.printStackTrace();
      
          }
      
      }
      

      【讨论】:

        【解决方案4】:

        在新的 facebook SDK 发布中,视频上传到 facebook 页面或墙有一些变化。

        这是我用于在 Facebook 页面或 Facebook 墙上上传视频的代码。

        你的onActivityResult()方法应该是这样的

        @Override
        protected void onActivityResult(int requestCode, int resultCode, Intent data) {
            super.onActivityResult(requestCode, resultCode, data);
            if(requestCode == CAMERA_VIDEO && resultCode == Activity.RESULT_OK){
                String selectedVideoFilePath = GetFilePathFromDevice.getPath(this, data.getData());   
                final byte[] datas = readBytes(selectedVideoFilePath);
                PostVideo(datas, selectedVideoFilePath);
            }
        }
        

        这是onActivityResult().中使用的所有方法

        public byte[] readBytes(String dataPath) throws IOException {
                InputStream inputStream = new FileInputStream(dataPath);
                ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream();
                byte[] buffer = new byte[1024];
                int len;
                while ((len = inputStream.read(buffer)) != -1) {
                    byteBuffer.write(buffer, 0, len);
                }
                return byteBuffer.toByteArray();
         }
        
        
        public void PostVideo(byte[] VideoBytes, String filePath) {
                String url;
                url = "/me/videos";
        
                AccessToken token = AccessToken.getCurrentAccessToken();
                if (token != null) {
                    Bundle param = new Bundle();
                    param.putByteArray("video." + getFileExt(filePath), VideoBytes);
                    param.putString("description", "sample video");
                    new GraphRequest(token,url, param, HttpMethod.POST, new GraphRequest.Callback() {
        
                        public void onCompleted(GraphResponse response) {
                            Log.e("New Post", "Res =" + response.toString());
                            dialog.dismiss();
        
                            if (response != null && response.getJSONObject() != null && response.getJSONObject().has("id")) {
                                Log.e("New Post", "Success");
                                Toast.makeText(NewPostActivity.this, "Video posted successfully.", Toast.LENGTH_SHORT).show();
                            } else {
                                Toast.makeText(NewPostActivity.this, "Error in posting Video.", Toast.LENGTH_SHORT).show();
                            }
                            setResult(Activity.RESULT_OK, new Intent());
                            finish();
                        }
                    }).executeAsync();
                }
         }
        
        public static String getFileExt(String fileName) {
                return fileName.substring((fileName.lastIndexOf(".") + 1), fileName.length());
        }
        

        这里是 onActivityResult() 中用于从 URI 获取文件路径的 GetFilePathFromDevice 类。

        @SuppressLint("NewApi")
        public final class GetFilePathFromDevice {
        
        /**
         * Get file path from URI
         *
         * @param context context of Activity
         * @param uri     uri of file
         * @return path of given URI
         */
        public static String getPath(final Context context, final Uri uri) {
            final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
            // DocumentProvider
            if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
                // ExternalStorageProvider
                if (isExternalStorageDocument(uri)) {
                    final String docId = DocumentsContract.getDocumentId(uri);
                    final String[] split = docId.split(":");
                    final String type = split[0];
                    if ("primary".equalsIgnoreCase(type)) {
                        return Environment.getExternalStorageDirectory() + "/" + split[1];
                    }
                }
                // DownloadsProvider
                else if (isDownloadsDocument(uri)) {
                    final String id = DocumentsContract.getDocumentId(uri);
                    final Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
                    return getDataColumn(context, contentUri, null, null);
                }
                // MediaProvider
                else if (isMediaDocument(uri)) {
                    final String docId = DocumentsContract.getDocumentId(uri);
                    final String[] split = docId.split(":");
                    final String type = split[0];
                    Uri contentUri = null;
                    if ("image".equals(type)) {
                        contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
                    } else if ("video".equals(type)) {
                        contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
                    } else if ("audio".equals(type)) {
                        contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
                    }
                    final String selection = "_id=?";
                    final String[] selectionArgs = new String[]{split[1]};
                    return getDataColumn(context, contentUri, selection, selectionArgs);
                }
            }
            // MediaStore (and general)
            else if ("content".equalsIgnoreCase(uri.getScheme())) {
                // Return the remote address
                if (isGooglePhotosUri(uri))
                    return uri.getLastPathSegment();
                return getDataColumn(context, uri, null, null);
            }
            // File
            else if ("file".equalsIgnoreCase(uri.getScheme())) {
                return uri.getPath();
            }
            return null;
        }
        
        public static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) {
            Cursor cursor = null;
            final String column = "_data";
            final String[] projection = {column};
            try {
                cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null);
                if (cursor != null && cursor.moveToFirst()) {
                    final int index = cursor.getColumnIndexOrThrow(column);
                    return cursor.getString(index);
                }
            } finally {
                if (cursor != null)
                    cursor.close();
            }
            return null;
        }
        
        public static boolean isExternalStorageDocument(Uri uri) {
            return "com.android.externalstorage.documents".equals(uri.getAuthority());
        }
        
        public static boolean isDownloadsDocument(Uri uri) {
            return "com.android.providers.downloads.documents".equals(uri.getAuthority());
        }
        
        public static boolean isMediaDocument(Uri uri) {
            return "com.android.providers.media.documents".equals(uri.getAuthority());
        }
        
        public static boolean isGooglePhotosUri(Uri uri) {
            return "com.google.android.apps.photos.content".equals(uri.getAuthority());
        }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-10-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-03-21
          相关资源
          最近更新 更多