如何使用我的android应用程序将视频上传到YouTube

如何使用我的android应用程序将视频上传到YouTube,android,android-youtube-api,Android,Android Youtube Api,如何从我的android应用程序上传视频到一个特定的YouTube账户,我一直在关注,但没有很好的文档记录 我试过了 public class YoutubeUploader { private static final String TAG = "YoutubeUploader"; // After creating project at http://www.appspot.com DEFAULT_YTD_DOMAIN == <Developers Console

如何从我的android应用程序上传视频到一个特定的YouTube账户,我一直在关注,但没有很好的文档记录

我试过了

public class YoutubeUploader {

    private static final String TAG = "YoutubeUploader";

    // After creating project at http://www.appspot.com DEFAULT_YTD_DOMAIN == <Developers Console Project ID>.appspot.com [ You can find from Project -> Administration -> Application settings]
    //public static final String DEFAULT_YTD_DOMAIN = "developerconsolid.appspot.com";

    // I used Google APIs Console Project Title as Domain name:
    //public static final String DEFAULT_YTD_DOMAIN_NAME = "Domain Name";

    //From Google Developer Console from same project (Created by SHA1; project package)
    //Example https://console.developers.google.com/project/apps~gtl-android-youtube-test/apiui/credential
    public static final String DEVELOPER_KEY = "AIzaSyAHY0NwfsfsffsfsfsfFYgC_TSnos1Tz_N_hk-jO20AeEk";

    // CLIENT_ID == Google APIs Console Project Number:
    public static final String CLIENT_ID = "157613";

    public static final String YOUTUBE_AUTH_TOKEN_TYPE = "youtube";

    private static final String AUTH_URL = "https://www.google.com/accounts/ClientLogin";



    // Uploader's user-name and password
    private static final String USER_NAME = "my@gmail.com";
    private static final String PASSWORD = "mypassword";

    private static final String INITIAL_UPLOAD_URL = "https://uploads.gdata.youtube.com/resumable/feeds/api/users/default/uploads";

    private static String getClientAuthToken() {

        try {

            URL url = new URL(AUTH_URL);

            HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
            urlConnection.setRequestMethod("POST");
            urlConnection.setDoOutput(true);
            urlConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");

            String template = "Email=%s&Passwd=%s&service=%s&source=%s";

            String userName = USER_NAME; // TODO
            String password = PASSWORD; // TODO

            String service = YOUTUBE_AUTH_TOKEN_TYPE;
            String source = CLIENT_ID;

            userName = URLEncoder.encode(userName, "UTF-8");
            password = URLEncoder.encode(password, "UTF-8");

            String loginData = String.format(template, userName, password, service, source);

            OutputStreamWriter outStreamWriter = new OutputStreamWriter(urlConnection.getOutputStream());
            outStreamWriter.write(loginData);
            outStreamWriter.close();

            int responseCode = urlConnection.getResponseCode();

            if (responseCode != 200) {

                Log.d(TAG, "Got an error response : " + responseCode + " "  + urlConnection.getResponseMessage());

                throw new IOException(urlConnection.getResponseMessage());

            } else {

                InputStream is = urlConnection.getInputStream();
                InputStreamReader isr = new InputStreamReader(is);
                BufferedReader br = new BufferedReader(isr);
                String line = null;

                while ((line = br.readLine()) != null) {

                    if (line.startsWith("Auth=")) {

                        String split[] = line.split("=");
                        String token = split[1];

                        Log.d(TAG, "Auth Token : " + token);
                        return token;
                    }
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    public static String upload(YoutubeUploadRequest uploadRequest, ProgressListner listner, Activity activity) {

        totalBytesUploaded = 0;

        String authToken = getClientAuthToken();

        if(authToken != null) {

            String uploadUrl = uploadMetaData(uploadRequest, authToken, activity, true);

            File file = getFileFromUri(uploadRequest.getUri(), activity);

            long currentFileSize = file.length();

            int uploadChunk = 1024 * 1024 * 3; // 3MB

            int start = 0;
            int end = -1;

            String videoId = null;

            double fileSize = currentFileSize;

            while (fileSize > 0) {

                if (fileSize - uploadChunk > 0) {
                    end = start + uploadChunk - 1;
                } else {
                    end = start + (int) fileSize - 1;
                }

                Log.d(TAG, String.format("start=%s end=%s total=%s", start, end, file.length()));

                try {

                    videoId = gdataUpload(file, uploadUrl, start, end, authToken, listner);
                    fileSize -= uploadChunk;
                    start = end + 1;
                } catch (IOException e) {
                    Log.d(TAG,"Error during upload : " + e.getMessage());
                }
            }

            if (videoId != null) {
                return videoId;
            }
        }

        return null;
    }

    public static int totalBytesUploaded = 0;

    @SuppressLint("DefaultLocale")
    @SuppressWarnings("resource")
    private static String gdataUpload(File file, String uploadUrl, int start, int end, String clientLoginToken, ProgressListner listner) throws IOException {

        int chunk = end - start + 1;
        int bufferSize = 4096;
        byte[] buffer = new byte[bufferSize];
        FileInputStream fileStream = new FileInputStream(file);

        URL url = new URL(uploadUrl);
        HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
        urlConnection.setRequestProperty("Authorization", String.format("GoogleLogin auth=\"%s\"",  clientLoginToken));
        urlConnection.setRequestProperty("GData-Version", "2");
        urlConnection.setRequestProperty("X-GData-Client", CLIENT_ID);
        urlConnection.setRequestProperty("X-GData-Key", String.format("key=%s", DEVELOPER_KEY));
        // some mobile proxies do not support PUT, using X-HTTP-Method-Override to get around this problem

        urlConnection.setRequestMethod("POST");
        urlConnection.setRequestProperty("X-HTTP-Method-Override", "PUT");
        urlConnection.setDoOutput(true);

        urlConnection.setFixedLengthStreamingMode(chunk);
        urlConnection.setRequestProperty("Content-Type", "video/3gpp");
        urlConnection.setRequestProperty("Content-Range", String.format("bytes %d-%d/%d", start, end,
                file.length()));

        Log.d(TAG, urlConnection.getRequestProperty("Content-Range"));

        OutputStream outStreamWriter = urlConnection.getOutputStream();

        fileStream.skip(start);

        double currentFileSize = file.length();

        int bytesRead;
        int totalRead = 0;
        while ((bytesRead = fileStream.read(buffer, 0, bufferSize)) != -1) {
            outStreamWriter.write(buffer, 0, bytesRead);
            totalRead += bytesRead;
            totalBytesUploaded += bytesRead;

            double percent = (totalBytesUploaded / currentFileSize) * 100;

            if(listner != null){
                listner.onUploadProgressUpdate((int) percent);
            }

            System.out.println("GTL You tube upload progress: " + percent + "%");
             /*
                Log.d(LOG_TAG, String.format(
                "fileSize=%f totalBytesUploaded=%f percent=%f", currentFileSize,
                totalBytesUploaded, percent));
             */

            //dialog.setProgress((int) percent);
            // TODO My settings

            if (totalRead == (end - start + 1)) {
                break;
            }
        }

        outStreamWriter.close();

        int responseCode = urlConnection.getResponseCode();

        Log.d(TAG, "responseCode=" + responseCode);
        Log.d(TAG, "responseMessage=" + urlConnection.getResponseMessage());

        try {
            if (responseCode == 201) {
                String videoId = parseVideoId(urlConnection.getInputStream());

                return videoId;
            } else if (responseCode == 200) {
                Set<String> keySet = urlConnection.getHeaderFields().keySet();
                String keys = urlConnection.getHeaderFields().keySet().toString();
                Log.d(TAG, String.format("Headers keys %s.", keys));
                for (String key : keySet) {
                    Log.d(TAG, String.format("Header key %s value %s.", key, urlConnection.getHeaderField(key)));
                }
                Log.w(TAG, "Received 200 response during resumable uploading");
                throw new IOException(String.format("Unexpected response code : responseCode=%d responseMessage=%s", responseCode,
                        urlConnection.getResponseMessage()));
            } else {
                if ((responseCode + "").startsWith("5")) {
                    String error = String.format("responseCode=%d responseMessage=%s", responseCode,
                            urlConnection.getResponseMessage());
                    Log.w(TAG, error);
                    // TODO - this exception will trigger retry mechanism to kick in
                    // TODO - even though it should not, consider introducing a new type so
                    // TODO - resume does not kick in upon 5xx
                    throw new IOException(error);
                } else if (responseCode == 308) {
                    // OK, the chunk completed succesfully
                    Log.d(TAG, String.format("responseCode=%d responseMessage=%s", responseCode,
                            urlConnection.getResponseMessage()));
                } else {
                    // TODO - this case is not handled properly yet
                    Log.w(TAG, String.format("Unexpected return code : %d %s while uploading :%s", responseCode,
                            urlConnection.getResponseMessage(), uploadUrl));
                }
            }
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            e.printStackTrace();
        }

        return null;
    }

    private static String parseVideoId(InputStream atomDataStream) throws ParserConfigurationException,
            SAXException, IOException {
        DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
        Document doc = docBuilder.parse(atomDataStream);

        NodeList nodes = doc.getElementsByTagNameNS("*", "*");
        for (int i = 0; i < nodes.getLength(); i++) {
            Node node = nodes.item(i);
            String nodeName = node.getNodeName();
            if (nodeName != null && nodeName.equals("yt:videoid")) {
                return node.getFirstChild().getNodeValue();
            }
        }
        return null;
    }

    private static File getFileFromUri(Uri uri, Activity activity) {

        try {
            String filePath = null;

            String[] proj = { Video.VideoColumns.DATA };

            Cursor cursor = activity.getContentResolver().query(uri, proj, null, null, null);

            if(cursor.moveToFirst()) {
                int column_index = cursor.getColumnIndexOrThrow(Video.VideoColumns.DATA);
                filePath = cursor.getString(column_index);
            }

            cursor.close();

            //String filePath = cursor.getString(cursor.getColumnIndex(Video.VideoColumns.DATA));

            File file = new File(filePath);
            cursor.close();
            return file;
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    private static String uploadMetaData(YoutubeUploadRequest uploadRequest, String clientLoginToken, Activity activity, boolean retry) {

        try {

            File file = getFileFromUri(uploadRequest.getUri(), activity);

            if(file != null) {

                String uploadUrl = INITIAL_UPLOAD_URL;
                URL url = new URL(uploadUrl);

                HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                connection.setRequestProperty("Authorization", String.format("GoogleLogin auth=\"%s\"", clientLoginToken));
                connection.setRequestProperty("GData-Version", "2");
                connection.setRequestProperty("X-GData-Client", CLIENT_ID);
                connection.setRequestProperty("X-GData-Key", String.format("key=%s", DEVELOPER_KEY));

                connection.setRequestMethod("POST");
                connection.setDoOutput(true);
                connection.setRequestProperty("Content-Type", "application/atom+xml");
                connection.setRequestProperty("Slug", file.getAbsolutePath());

                String title = uploadRequest.getTitle();
                String description = uploadRequest.getDescription();
                String category = uploadRequest.getCategory();
                String tags = uploadRequest.getTags();

                String template = readFile(activity, R.raw.gdata).toString();
                String atomData = String.format(template, title, description, category, tags);

                /*String template = readFile(activity, R.raw.gdata_geo).toString();
                atomData = String.format(template, title, description, category, tags,
                    videoLocation.getLatitude(), videoLocation.getLongitude());*/

                OutputStreamWriter outStreamWriter = new OutputStreamWriter(connection.getOutputStream());
                outStreamWriter.write(atomData);
                outStreamWriter.close();

                int responseCode = connection.getResponseCode();

                if (responseCode < 200 || responseCode >= 300) {

                    // The response code is 40X

                    if ((responseCode + "").startsWith("4") && retry) {

                        Log.d(TAG, "retrying to fetch auth token for ");

                        clientLoginToken = getClientAuthToken();

                        // Try again with fresh token
                        return uploadMetaData(uploadRequest, clientLoginToken, activity, false);
                    } else {
                        return null;
                    }
                }

                return connection.getHeaderField("Location");
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    public static CharSequence readFile(Activity activity, int id) {
        BufferedReader in = null;
        try {
            in = new BufferedReader(new InputStreamReader(activity.getResources().openRawResource(id)));
            String line;
            StringBuilder buffer = new StringBuilder();
            while ((line = in.readLine()) != null) {
                buffer.append(line).append('\n');
            }
            // Chomp the last newline
            buffer.deleteCharAt(buffer.length() - 1);
            return buffer;
        } catch (IOException e) {
            return "";
        } finally {
            closeStream(in);
        }
    }

    /**
     * Closes the specified stream.
     *
     * @param stream The stream to close.
     */
    private static void closeStream(Closeable stream) {
        if (stream != null) {
            try {
                stream.close();
            } catch (IOException e) {
                // Ignore
            }
        }
    }

    public static interface ProgressListner {

        void onUploadProgressUpdate(int progress);
    }
公共类YoutubeUploader{
私有静态最终字符串TAG=“YoutubeUploader”;
//在创建项目之后http://www.appspot.com 默认的_YTD_DOMAIN==.appspot.com[您可以在项目->管理->应用程序设置中找到]
//公共静态最终字符串DEFAULT\u YTD\u DOMAIN=“developerconsolid.appspot.com”;
//我使用Google API控制台项目标题作为域名:
//公共静态最终字符串DEFAULT\u YTD\u DOMAIN\u NAME=“DOMAIN NAME”;
//来自同一项目的Google开发者控制台(由SHA1创建;项目包)
//范例https://console.developers.google.com/project/apps~gtl android youtube测试/APUI/credential
public static final String DEVELOPER_KEY=“aizasyahy0nwfsfffygc_TSnos1Tz_N_hk-jo20aek”;
//CLIENT_ID==谷歌API控制台项目编号:
公共静态最终字符串客户端\u ID=“157613”;
公共静态最终字符串YOUTUBE\u AUTH\u TOKEN\u TYPE=“YOUTUBE”;
私有静态最终字符串AUTH_URL=”https://www.google.com/accounts/ClientLogin";
//上传者的用户名和密码
私有静态最终字符串USER_NAME=”my@gmail.com";
私有静态最终字符串PASSWORD=“mypassword”;
私有静态最终字符串初始\u上载\u URL=”https://uploads.gdata.youtube.com/resumable/feeds/api/users/default/uploads";
私有静态字符串getClientAuthToken(){
试一试{
URL URL=新URL(验证URL);
HttpURLConnection urlConnection=(HttpURLConnection)url.openConnection();
urlConnection.setRequestMethod(“POST”);
urlConnection.setDoOutput(true);
setRequestProperty(“内容类型”,“应用程序/x-www-form-urlencoded”);
String template=“电子邮件=%s&Passwd=%s&service=%s&source=%s”;
字符串userName=USER_NAME;//TODO
字符串password=password;//TODO
String service=YOUTUBE\u AUTH\u TOKEN\u TYPE;
字符串源=客户端ID;
userName=URLEncoder.encode(用户名,“UTF-8”);
password=URLEncoder.encode(密码“UTF-8”);
String loginda=String.format(模板、用户名、密码、服务、源);
OutputStreamWriter outStreamWriter=新的OutputStreamWriter(urlConnection.getOutputStream());
outStreamWriter.write(登录数据);
outStreamWriter.close();
int responseCode=urlConnection.getResponseCode();
如果(响应代码!=200){
Log.d(标记“获得错误响应:”+responseCode+“”+urlConnection.getResponseMessage());
抛出新IOException(urlConnection.getResponseMessage());
}否则{
InputStream is=urlConnection.getInputStream();
InputStreamReader isr=新的InputStreamReader(is);
BufferedReader br=新的BufferedReader(isr);
字符串行=null;
而((line=br.readLine())!=null){
if(line.startsWith(“Auth=)){
字符串拆分[]=line.split(“=”);
字符串标记=拆分[1];
Log.d(标记“身份验证令牌:”+令牌);
返回令牌;
}
}
}
}捕获(例外e){
e、 printStackTrace();
}
返回null;
}
公共静态字符串上载(YoutubeUploadRequest uploadRequest、ProgressListner、listner、Activity){
TotalBytesUpload=0;
字符串authToken=getClientAuthToken();
if(authToken!=null){
String uploadUrl=uploadMetaData(uploadRequest、authToken、activity、true);
File File=getFileFromUri(uploadRequest.getUri(),activity);
long currentFileSize=file.length();
int uploadChunk=1024*1024*3;//3MB
int start=0;
int end=-1;
字符串videoId=null;
双文件大小=当前文件大小;
而(文件大小>0){
如果(文件大小-上载块>0){
end=start+uploadChunk-1;
}否则{
end=start+(int)文件大小-1;
}
Log.d(标记,字符串.format(“开始=%s结束=%s总计=%s”,开始,结束,文件.length());
试一试{
videoId=gdataUpload(文件、上传URL、开始、结束、authToken、listner);
fileSize-=上传块;
开始=结束+1;
}捕获(IOE异常){
Log.d(标记“上传时出错:”+e.getMessage());
}
}
if(videoId!=null){
返回videoId;
}
}
返回null;
}
公共静态int TotalBytesUpload=0;
@SuppressLint(“DefaultLocale”)
@抑制警告(“资源”)
私有静态字符串gdataUpload(文件文件、字符串上载URL、int-start、int-end、字符串clientLoginToken、ProgressListner-listner)引发IOException{
int chunk=end-start+1;
int bufferSize=4096;
字节[]缓冲区=新字节[bufferSize];
FileInputStream fileStream=新的FileInputStream(文件);
URL=新URL(上传URL);
HttpURLConnection urlConnection=(HttpURLConnection)url.openConnection();
urlConnection.setRequestProperty(“授权”,String.format(“GoogleLogin auth=\%s\”,clientLoginToken));
setRequestProperty(“GData版本”,“2”);
setRequestProperty(“X-GData-Client”,客户端ID);
urlConnection.setRequestProperty(“X-GData-Key”,String.format(“Key=%s”,DEVELOPER_Key));
//某些移动代理不支持