GithubHelp home page GithubHelp logo

yt-watchme's People

Contributors

bonnyfone avatar dariol avatar ulukaya avatar vshcryabets avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

yt-watchme's Issues

How to build fdk-aac with ffmpeg?

I enabled --enable-libfdk-aac , --enable-nonfree flags in ffmpeg configuration
but how to configure libfdk aac and include while building ffmpeg source code?

FATAL EXCEPTION, when I select event

This is the log I got, Can some help me out?

10-26 19:05:59.160 31881-31881/com.google.android.apps.watchme E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.google.android.apps.watchme, PID: 31881
java.lang.NoSuchMethodError: No virtual method checkSelfPermission(Ljava/lang/String;)I in class Lcom/google/android/apps/watchme/StreamerActivity; or its super classes (declaration of 'com.google.android.apps.watchme.StreamerActivity' appears in /data/data/com.google.android.apps.watchme/files/instant-run/dex/slice-slice_2-classes.dex)
at com.google.android.apps.watchme.StreamerActivity.startStreaming(StreamerActivity.java:174)
at com.google.android.apps.watchme.StreamerActivity.access$200(StreamerActivity.java:46)
at com.google.android.apps.watchme.StreamerActivity$1.onServiceConnected(StreamerActivity.java:66)
at android.app.LoadedApk$ServiceDispatcher.doConnected(LoadedApk.java:1266)
at android.app.LoadedApk$ServiceDispatcher$RunConnection.run(LoadedApk.java:1283)
at android.os.Handler.handleCallback(Handler.java:815)
at android.os.Handler.dispatchMessage(Handler.java:104)
at android.os.Looper.loop(Looper.java:194)
at android.app.ActivityThread.main(ActivityThread.java:5706)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1033)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:828)

src/main/jniLibs/armeabi file not found

Hi,
I have done 1st, 2nd point from readme.md, Can some give more clarity on the rest of the points(3,4)

  1. Is 3rd point mandatory?
  2. In 4th point, I don't have file src/main/jniLibs/armeabi

what to do??

ffmpeg-jni.c - Format not a string literal and no format arguments

jni/ffmpeg-jni.c: In function 'log_callback':
jni/ffmpeg-jni.c:84:3: error: format not a string literal and no format arguments [-Werror=format-security]
.
.
.
cc1: some warnings being treated as errors

make: *** [obj/local/armeabi/objs/ffmpeg/ffmpeg-jni.o] Error 1

There seems to be some issue with the log_callback function in ffmpeg-jni.c? Pls help.

Pls update the guide to build this app

I have followed the guide and tried in many different ways to build ffmpeg and include in the project but something somewhere doesn't work always. Its been year since this project was published. Isn't there alternate way of running this project as it is?
Please someone who succeeded in running this app, provide with updated set of steps specially for ppl like me who are not proficient with NDK and ffmpeg.
Thanks in advance.

Result not loading

public ResultsData(Activity activity,
        ExpandableListView resultsView, boolean[] resultsExpanded,
        ExpandableListView detailsView, boolean[] detailsExpanded, String dbName) {
    mActivity = activity;
    mResultsView = resultsView;
    mDetailsView = detailsView;
    mResultsExpanded = resultsExpanded;
    mDetailsExpanded = detailsExpanded;
    mDbName = dbName;
}

public void loadResults() {
    new ReadDbTask().execute(mDbName);
}

/*private View getPsCallView(PsCallResults results) {
    View layout = getLayoutInflater().inflate(R.layout.results_pscall, null);

    Utils.setTextViewText(layout, R.id.setup_times, getString(
            R.string.ps_times, results.minAttach / 1000f,
            results.avgAttach / 1000f, results.maxAttach / 1000f));
    Utils.setTextViewText(layout, R.id.release_times, getString(
            R.string.ps_times, results.minDetach / 1000f,
            results.avgDetach / 1000f, results.maxDetach / 1000f));
    Utils.setTextViewText(layout, R.id.setup_success,
            String.format("%d/%d (%d %%)",
                    results.successfulAttaches, mConfig.iterations,
                    100 * results.successfulAttaches / mConfig.iterations));
    Utils.setTextViewText(layout, R.id.release_success,
            String.format("%d/%d (%d %%)",
                    results.successfulDetaches, mConfig.iterations,
                    100 * results.successfulDetaches / mConfig.iterations));
    return layout;
}*/

@SuppressLint("InflateParams")
private View getPingView(PingResults results) {
    View layout = getLayoutInflater().inflate(R.layout.results_ping, null);

    String host = mConfig.pingHost;
    if (results.successfulIterations > 0) {
        host += " (" + mPingIp + ")";
    }

    Utils.setTextViewText(layout, R.id.host, host);
    CharSequence text = Html.fromHtml(getString(R.string.ping_packets,
            results.sent, results.received, results.lost,
            (results.sent == 0 ? 0 : results.lost * 100 / results.sent)));
    Utils.setTextViewSpannable(layout, R.id.packets, text);
    Utils.setTextViewText(layout, R.id.rtt, getString(R.string.ping_rtt,
            results.min, results.avg, results.max));
    Utils.setTextViewText(layout, R.id.success_rate,
            String.format("%d/%d (%d %%)",
                    results.successfulIterations, mConfig.iterations,
                    100 * results.successfulIterations / mConfig.iterations));
    return layout;
}

private View getSpeedView(SpeedTestResult result) {
    LinearLayout layout = (LinearLayout) getLayoutInflater().inflate(
            R.layout.results_speed, null);

    if (mConfig.ftpFileSize == 0L) {
        TableLayout table = (TableLayout) layout.findViewById(R.id.table);
        table.setColumnCollapsed(2, true);
    }

    Utils.setTextViewSpannable(layout, R.id.download_average,
            getThroughputSpannable(true, getColorString(R.color.dl_avg),
                    result.dlResult.avgBps));
    Utils.setTextViewSpannable(layout, R.id.download_peak,
            getThroughputSpannable(true, getColorString(R.color.dl_peak),
                    result.dlResult.peakBps));
    Utils.setTextViewText(layout, R.id.download_filesize,
            Formatter.formatShortFileSize(mActivity, mDownloadFileSize)
            + (mConfig.ftpConnections == 1 ?
                    "" : " x " + mConfig.ftpConnections));
    Utils.setTextViewText(layout, R.id.download_iterations,
            String.valueOf(result.dlResult.iterations.size()));

    if (mConfig.ftpFileSize != 0L) {
        Utils.setTextViewSpannable(layout, R.id.upload_average,
                getThroughputSpannable(false, getColorString(R.color.ul_avg),
                        result.ulResult.avgBps));
        Utils.setTextViewSpannable(layout, R.id.upload_peak,
                getThroughputSpannable(false, getColorString(R.color.ul_peak),
                        result.ulResult.peakBps));
        Utils.setTextViewText(layout, R.id.upload_filesize,
                Formatter.formatShortFileSize(mActivity, mConfig.ftpFileSize)
                + (mConfig.ftpConnections == 1 ?
                        "" : " x " + mConfig.ftpConnections));
        Utils.setTextViewText(layout, R.id.upload_iterations,
                String.valueOf(result.ulResult.iterations.size()));
    }

    Utils.setTextViewText(layout, R.id.server_value, mConfig.ftpServer);

    LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
            LayoutParams.MATCH_PARENT, getDimension(R.dimen.speedchart_height));
    layoutParams.topMargin = getDimension(R.dimen.speedchart_topmargin);

    final boolean useMbps = shouldUseMbps(result);
    View chartView = getSpeedChartView(result.dlResult, true, useMbps);
    if (chartView != null) {
        layout.addView(chartView , layoutParams);
    }
    if (mConfig.ftpFileSize != 0L) {
        chartView = getSpeedChartView(result.ulResult, false, useMbps);
        if (chartView != null) {
            layout.addView(chartView, layoutParams);
        }
    }
    return layout;
}

private View getSpeedChartView(final FtpResult result, final boolean isDownload,
        final boolean useMbps) {
    AbstractChart chart = getSpeedChart(result, isDownload, useMbps,
            createXYMultipleSeriesRenderer(isDownload, useMbps, false));
    if (chart == null) {
        return null;
    }

    View view = new GraphicalView(mActivity, chart);
    view.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {

            mActivity.startActivity(new Intent(mActivity, GraphicalActivity.class)
                .putExtra(ChartFactory.CHART,
                        getSpeedChart(result, isDownload, useMbps,
                                createXYMultipleSeriesRenderer(
                                        isDownload, useMbps, true)))
                .putExtra(ChartFactory.TITLE, (String) null));
        }
    });
    return view;
}


@SuppressWarnings("deprecation")
private AbstractChart getSpeedChart(FtpResult result, boolean isDownload,
        boolean useMbps, XYMultipleSeriesRenderer renderer) {
    if (mConfig.iterations == 1) {
        return result.iterations.size() > 0 ?
                getSpeedTimeChart(result.iterations.get(0),
                        isDownload, useMbps, renderer) : null;
    }

    int seriesTitle;
    int[] colors;
    if (isDownload) {
        seriesTitle = R.string.dl_throughput;
        colors = new int[]{R.color.dl_throughput, R.color.dl_peak, R.color.dl_fill};
    } else {
        seriesTitle = R.string.ul_throughput;
        colors = new int[]{R.color.ul_throughput, R.color.ul_peak, R.color.ul_fill};
    }
    if (result.iterations.size() == 0) {
        return null;
    }

    XYMultipleSeriesDataset dataset = new XYMultipleSeriesDataset();

    // Average line
    dataset.addSeries(getAverageSeries(result.avgBps, 1, result.iterations.size() - 1,
            isDownload, useMbps));
    XYSeriesRenderer r = new XYSeriesRenderer();
    r.setColor(0xff9999FF); //getColor(isDownload ? R.color.dl_avg : R.color.ul_avg));
    renderer.addSeriesRenderer(r);

    // Throughput bars
    XYSeries series = getXYSeries(result, getString(seriesTitle), useMbps);
    dataset.addSeries(series);
    r = new XYSeriesRenderer();
    r.setColor(getColor(colors[0]));
    r.setFillBelowLine(true);
    r.setFillBelowLineColor(getColor(colors[2]));
    r.setLineWidth(getDimension(R.dimen.speedchart_line_width));
    renderer.addSeriesRenderer(r);

    renderer.setXTitle(getString(R.string.iterations));
    renderer.setPanLimits(new double[]{
            series.getMinX() - 1D, series.getMaxX() + 1D,
            series.getMinY(), series.getMaxY()});
    renderer.setInitialRange(new double[]{series.getItemCount() > 30 ?
            series.getX(series.getItemCount() - 30) : series.getMinX(),
            series.getMaxX(), series.getMinY(), series.getMaxY()});
    renderer.setXLabels(
            Math.min(renderer.getXLabels() - 1, result.iterations.size() - 2));
    renderer.setYAxisMin(Math.max(0D, series.getMinY() - 0.5D));
    renderer.setBarSpacing(0.618);

    int[] margins = renderer.getMargins();
    margins[1] += 6;
    margins[2] = (int) (renderer.getLegendTextSize() + 1);
    renderer.setMargins(margins);

    CombinedXYChart chart = new CombinedXYChart(dataset, renderer,
            new String[] {LineChart.TYPE, BarChart.TYPE});
    new FitZoom(chart).apply();
    return chart;
}

@SuppressWarnings("deprecation")
private LineChart getSpeedTimeChart(SpeedTestIteration iteration,
        boolean isDownload, boolean useMbps, XYMultipleSeriesRenderer renderer) {
    if (iteration == null) {
        return null;
    }

    final int seriesLabelId, lineColorId, fillColorId;
    if (isDownload) {
        seriesLabelId = R.string.dl_throughput;
        lineColorId = R.color.dl_throughput;
        fillColorId = R.color.dl_fill;
    } else {
        seriesLabelId = R.string.ul_throughput;
        lineColorId = R.color.ul_throughput;
        fillColorId = R.color.ul_fill;
    }

    final int count = iteration.throughputs.size();
    if (count == 0) {
        return null;
    }

    XYMultipleSeriesDataset dataset = new XYMultipleSeriesDataset();

    // Average line
    dataset.addSeries(getAverageSeries(iteration.avgBps, 0,
            iteration.throughputs.get(count - 1).timestamp -
            iteration.throughputs.get(0).timestamp, isDownload, useMbps));
    XYSeriesRenderer r = new XYSeriesRenderer();
    r.setColor(0xff9999FF); //getColor(isDownload ? R.color.dl_avg : R.color.ul_avg));
    renderer.addSeriesRenderer(r);

    // Throughput line
    XYSeries series = getTimeThroughputSeries(iteration, seriesLabelId, useMbps);
    dataset.addSeries(series);
    r = new XYSeriesRenderer();
    r.setColor(getColor(lineColorId));
    r.setFillBelowLine(true);
    r.setFillBelowLineColor(getColor(fillColorId));
    r.setLineWidth(getDimension(R.dimen.speedchart_line_width));
    renderer.addSeriesRenderer(r);

    renderer.setXTitle(getString(R.string.time));
    renderer.setPanLimits(new double[]{
            series.getMinX() - 1D, series.getMaxX() + 1D,
            series.getMinY(), series.getMaxY()});
    renderer.setInitialRange(new double[]{series.getItemCount() > 30 ?
            series.getX(series.getItemCount() - 30) : series.getMinX(),
            series.getMaxX(), series.getMinY(), series.getMaxY()});
    renderer.setYAxisMin(Math.max(0D, series.getMinY() - 0.5D));

    int[] margins = renderer.getMargins();
    margins[1] += 6;
    margins[2] = (int) (renderer.getLegendTextSize() + 1);
    renderer.setMargins(margins);

    LineChart chart = new TimeChart(dataset, renderer, 0.1f);
    new FitZoom(chart).apply();
    return chart;
}

private XYSeries getAverageSeries(long avgBps, long xMin, long xMax,
        boolean isDownload, boolean useMbps) {
    XYSeries series = new XYSeries(
            getString(isDownload ? R.string.dl_avg : R.string.ul_avg));
    final double avgThroughput = getThroughput(avgBps, useMbps);
    series.add(xMin, avgThroughput);
    series.add(xMax, avgThroughput);
    return series;
}

private XYMultipleSeriesRenderer createXYMultipleSeriesRenderer(
        boolean isDownload, boolean useMbps, boolean inActivity) {
    XYMultipleSeriesRenderer renderer = new XYMultipleSeriesRenderer();
    renderer.setChartTitleTextSize(
            getDimension(R.dimen.speedchart_title_text_size));
    renderer.setAxisTitleTextSize(
            getDimension(R.dimen.speedchart_axis_text_size));
    renderer.setFitLegend(true);
    renderer.setLegendTextSize(
            getDimension(R.dimen.speedchart_legend_text_size));
    renderer.setShowGrid(true);
    renderer.setYLabelsAlign(Align.RIGHT);
    renderer.setXLabelsAlign(Align.CENTER);
    renderer.setYTitle(useMbps ? "Mbps" : "Kbps");
    renderer.setClickEnabled(!inActivity);
    renderer.setPanEnabled(inActivity, false);
    renderer.setZoomEnabled(inActivity, false);
    renderer.setZoomButtonsVisible(inActivity);
    renderer.setInScroll(!inActivity);
    return renderer;
}

private XYSeries getTimeThroughputSeries(SpeedTestIteration iteration,
        int seriesLabelId, boolean useMbps) {
    final long firstTimestamp;
    final Throughput firstThroughput = iteration.throughputs.get(0);
    firstTimestamp = firstThroughput != null ? firstThroughput.timestamp : 0;

    XYSeries series = new XYSeries(getString(seriesLabelId));
    for (Throughput throughput : iteration.throughputs) {
        series.add(throughput.timestamp - firstTimestamp,
                getThroughput(throughput.bytesPerSec, useMbps));
    }
    return series;
}

private XYSeries getXYSeries(FtpResult result, String label, boolean useMbps) {
    XYSeries series = new XYSeries(label);
    for (SpeedTestIteration iteration : result.iterations) {
        series.add(iteration.iteration,
                getThroughput(iteration.avgBps, useMbps));
    }
    return series;
}

private double getThroughput(long bytesPerSec, boolean useMbps) {
    final long bps = bytesPerSec * 8;
    return useMbps ? bps / (1024D * 1024D) : bps / 1024D;
    // Round to one decimal point (better for display)

// return Math.round(throughput * 10D) / 10D;
}

private CharSequence getThroughputSpannable(boolean isDownload,
        String color, long bytesPerSec) {
    long bps = bytesPerSec * 8;
    boolean useMbps = (bps >= 1024 * 1024);
    double throughput = bps / (useMbps ? 1024D * 1024D : 1024D);
    String s = getString(R.string.arrow_throughput, color,
            isDownload ? "\u2193" : "\u2191", throughput,
            (useMbps ? "Mbps" : "Kbps"));
    return Html.fromHtml(s);
}

private boolean shouldUseMbps(SpeedTestResult result) {
    final long M = 1024 * 1024;
    return result.dlResult.peakBps * 8 >= M || result.ulResult.peakBps * 8 >= M;
}

@SuppressLint("InflateParams")
private View getCallView(CallTestResults results) {
    final int counts[] = new int[] {results.successful, results.failed};
    final int colors[] = new int[] {Color.GREEN, Color.RED};
    final String[] strings = getResources().getStringArray(
            R.array.call_result_formats);

    CategorySeries dataset = new CategorySeries("");
    DefaultRenderer renderer = new DefaultRenderer();
    SimpleSeriesRenderer seriesRenderer;

    for (int i = 0; i < counts.length; ++i) {
        dataset.add(String.format(strings[i], counts[i]), counts[i]);
        seriesRenderer = new SimpleSeriesRenderer();
        seriesRenderer.setColor(colors[i]);
        renderer.addSeriesRenderer(seriesRenderer);
    }

    renderer.setStartAngle(90);
    renderer.setInScroll(true);
    renderer.setPanEnabled(false);
    renderer.setZoomEnabled(false);
    renderer.setShowLegend(false);

    GraphicalView chartView = ChartFactory.getPieChartView(mActivity,
            dataset, renderer);
    LinearLayout layout = (LinearLayout) getLayoutInflater().inflate(
            R.layout.results_call, null);
    layout.addView(chartView, 2, new LayoutParams(LayoutParams.MATCH_PARENT,
            getDimension(R.dimen.callchart_height)));

    Utils.setTextViewText(layout, R.id.calls_attempted,
            String.valueOf(results.attempted));
    Utils.setTextViewText(layout, R.id.calls_successful,
            String.valueOf(results.successful));
    Utils.setTextViewText(layout, R.id.calls_failed,
            String.valueOf(results.failed));
    Utils.setTextViewText(layout, R.id.call_setup_rate,
            (results.attempted == 0 ? 0
                    : results.successful * 100 / results.attempted) + "%");
    Utils.setTextViewText(layout, R.id.phone_number, mConfig.phoneNumber);

    if (results.successful > 0) {
        Utils.setTextViewText(layout, R.id.call_setup_times, getString(
                R.string.setup_times_format, results.minSetupTime / 1000f,
                results.avgSetupTime / 1000f, results.maxSetupTime / 1000f));
    } else {
        layout.findViewById(R.id.call_setup_times_label).setVisibility(
                View.GONE);
        layout.findViewById(R.id.call_setup_times).setVisibility(View.GONE);
    }
    return layout;
}

private Resources getResources() {
    return mActivity.getResources();
}

private String getString(int id, Object... formatArgs) {
    return mActivity.getResources().getString(id, formatArgs);
}

private int getDimension(int resid) {
    return mActivity.getResources().getDimensionPixelSize(resid);
}

private int getColor(int color) {
    return mActivity.getResources().getColor(color);
}

private String getColorString(int color) {
    TypedValue value = new TypedValue();
    getResources().getValue(color, value, false);
    // Remove the alpha value
    return "#" + value.coerceToString().toString().substring(3);
}

private LayoutInflater getLayoutInflater() {
    return (LayoutInflater) mActivity.getSystemService(
            Context.LAYOUT_INFLATER_SERVICE);
}

private class ReadDbTask extends AsyncTask<String, Void, List<Results>> {

    @Override
    protected void onPreExecute() {
        mActivity.setProgressBarIndeterminateVisibility(true);
    }

    @Override
    protected List<Results> doInBackground(String... dbNames) {
        List<Results> list = new ArrayList<Results>();
        Database db = null;
        Cursor c = null;

        try {
            db = Database.openDatabase(mActivity, dbNames[0]);
            c = db.getConfigCursor();
            mConfig = Database.getCampaignConfig(c);
            mPingIp = Database.getPingResolvedIp(c);
            mDownloadFileSize = Database.getFtpDownloadSize(c);

            Results results;
            for (TestType type : TestType.values()) {
                if ((results = db.getResults(type)) != null) {
                    list.add(results);
                }
            }
        } catch (Exception e) {
            Log.e(e.getMessage(), e);
            return null;
        } finally {
            if (c != null) {
                c.close();
            }
            if (db != null) {
                db.closeDatabase();
            }
        }
        return list;
    }

    @Override
    protected void onPostExecute(List<Results> list) {
        if (list == null) {
            Toast.makeText(mActivity.getApplicationContext(), R.string.generic_error,
                    Toast.LENGTH_SHORT).show();
            return;
        }

        mActivity.setTitle(mConfig.campaignName);
        mActivity.setProgressBarIndeterminateVisibility(false);

        mResultsView.setAdapter(new ResultsExpandableListAdapter(list));
        expandGroup(mResultsView, mResultsExpanded);
        mDetailsView.setAdapter(new DetailsExpandableListAdapter(list));
        expandGroup(mDetailsView, mDetailsExpanded);
    }

    private void expandGroup(ExpandableListView expandableListView,
            boolean[] expandedStates) {
        if (expandedStates != null) {
            final int count = expandableListView.getExpandableListAdapter().getGroupCount();
            for (int i = 0; i < count; i++) {
                if (expandedStates[i]) {
                    expandableListView.expandGroup(i);
                }
            }
        }
    }
}

private class ResultsExpandableListAdapter extends BaseExpandableListAdapter {

    private List<Results> mResultsList;

    public ResultsExpandableListAdapter(List<Results> resultsList) {
        mResultsList = resultsList;
    }

    @Override
    public Object getChild(int groupPosition, int childPosition) {
        return mResultsList.get(groupPosition);
    }

    @Override
    public long getChildId(int groupPosition, int childPosition) {
        return childPosition;
    }

    @Override
    public View getChildView(int groupPosition, int childPosition,
            boolean isLastChild, View convertView, ViewGroup parent) {
        if (convertView == null) {
            Results results = mResultsList.get(groupPosition);
            switch (results.testType) {
           // case PS_CALL_TEST: return getPsCallView((PsCallResults) results);
            case PING_TEST: return getPingView((PingResults) results);
            case SPEED_TEST: return getSpeedView((SpeedTestResult) results);
            case CALL_TEST: return getCallView((CallTestResults) results);
            }
        }
        return convertView;
    }

    @Override
    public int getChildrenCount(int groupPosition) {
        return 1;
    }

    @Override
    public TestType getGroup(int groupPosition) {
        return mResultsList.get(groupPosition).testType;
    }

    @Override
    public int getGroupCount() {
        return mResultsList.size();
    }

    @Override
    public long getGroupId(int groupPosition) {
        return groupPosition;
    }

    @Override
    public View getGroupView(int groupPosition, boolean isExpanded,
            View convertView, ViewGroup parent) {
        TextView textView = (TextView) convertView;
        if (textView == null) {
            textView = (TextView) getLayoutInflater().inflate(
                    R.layout.ongoing_group, null);
        }
        textView.setText(getGroup(groupPosition).toString(mActivity));
        return textView;
    }

    @Override
    public boolean hasStableIds() {
        return true;
    }

    @Override
    public boolean isChildSelectable(int groupPosition, int childPosition) {
        return false;
    }

    @Override
    public int getChildType(int groupPosition, int childPosition) {
        return groupPosition;
    }

    @Override
    public int getChildTypeCount() {
        return mResultsList.size();
    }
}


/*private final class PsCallAdapter extends ResultsTableAdapter {

    private final List<PsCallIteration> mIterations;

    private ResultsTableAdapter.Column[] columns =
            new ResultsTableAdapter.Column[] {
            new ResultsTableAdapter.Column() {
                @SuppressLint("SimpleDateFormat")
                private final DateFormat mDf =
                new SimpleDateFormat("MM-dd HH:mm:ss");

                @Override
                protected int computeWidth() {
                    return MARGIN + getTextWidth("W", mPaints[0]) +
                            getTextWidthForRow(mIterations.size() - 1, mPaints[0]);
                }

                @Override
                public String getCellString(int row) {
                    if (row == -1) {
                        return mActivity.getString(R.string.timestamp);
                    }
                    return mDf.format(new Date(
                            mIterations.get(row).startTime));
                }
            },
            new ResultsTableAdapter.Column() {
                @Override
                protected int computeWidth() {
                    return (MARGIN + getTextWidthForRow(-1, mPaints[0]));
                }

                @Override
                public boolean isColumnRightAligned() {
                    return true;
                }

                @Override
                public String getCellString(int row) {
                    if (row == -1) {
                        return mActivity.getString(R.string.ps_setup_time);
                    }
                    return String.valueOf(mIterations.get(row).attachTime);
                }
            },
            new ResultsTableAdapter.Column() {
                @Override
                protected int computeWidth() {
                    return (MARGIN + getTextWidthForRow(-1, mPaints[0]));
                }

                @Override
                public boolean isColumnRightAligned() {
                    return true;
                }

                @Override
                public String getCellString(int row) {
                    if (row == -1) {
                        return mActivity.getString(R.string.ps_release_time);
                    }
                    return String.valueOf(mIterations.get(row).detachTime);
                }
            },
    };

    public PsCallAdapter(PsCallResults results) {
        super(results.iterations.size(), getLayoutInflater());
        mIterations = results.iterations;
        initColumns(columns);
    }
}*/

private final class PingAdapter extends ResultsTableAdapter {

    private final List<PingTestIteration> mIterations;

    private ResultsTableAdapter.Column[] columns =
            new ResultsTableAdapter.Column[] {
            new ResultsTableAdapter.Column() {
                @SuppressLint("SimpleDateFormat")
                private final DateFormat mDf =
                new SimpleDateFormat("MM-dd HH:mm:ss");

                @Override
                protected int computeWidth() {
                    return MARGIN + getTextWidth("W", mPaints[0]) +
                            getTextWidthForRow(mIterations.size() - 1, mPaints[0]);
                }

                @Override
                public String getCellString(int row) {
                    if (row == -1) {
                        return mActivity.getString(R.string.timestamp);
                    }
                    return mDf.format(new Date(
                            mIterations.get(row).starttime));
                }
            },

            new ResultsTableAdapter.Column() {
                @Override
                protected int computeWidth() {
                    return MARGIN + getTextWidthForRow(-1, mPaints[0]);
                }

                @Override
                public boolean isColumnRightAligned() {
                    return true;
                }

                @Override
                public String getCellString(int row) {
                    return (row == -1) ?
                            mActivity.getString(R.string.packetsize) : "64";
                }
            },

            new ResultsTableAdapter.Column() {
                @Override
                protected int computeWidth() {
                    return (MARGIN + getTextWidthForRow(-1, mPaints[0]));
                }

                @Override
                public boolean isColumnRightAligned() {
                    return true;
                }

                @Override
                public String getCellString(int row) {
                    if (row == -1) {
                        return mActivity.getString(R.string.rttavg);
                    }
                    return String.valueOf(mIterations.get(row).avg);
                }
            },

            new ResultsTableAdapter.Column() {
                @Override
                protected int computeWidth() {
                    return (MARGIN + getTextWidthForRow(-1, mPaints[0]));
                }

                @Override
                public boolean isColumnRightAligned() {
                    return true;
                }

                @Override
                public String getCellString(int row) {
                    if (row == -1) {
                        return mActivity.getString(R.string.sent);
                    }
                    return String.valueOf(mIterations.get(row).sent);
                }
            },

            new ResultsTableAdapter.Column() {
                @Override
                protected int computeWidth() {
                    return (MARGIN + getTextWidthForRow(-1, mPaints[0]));
                }

                @Override
                public boolean isColumnRightAligned() {
                    return true;
                }

                @Override
                public String getCellString(int row) {
                    if (row == -1) {
                        return mActivity.getString(R.string.received);
                    }
                    return String.valueOf(mIterations.get(row).received);
                }
            },

            new ResultsTableAdapter.Column() {
                @Override
                protected int computeWidth() {
                    int width = getTextWidthForRow(-1, mPaints[0]);
                    int row = 0;

                    for (PingTestIteration it : mIterations) {
                        if (!ProgressHandler.PING_OK.equals(it.status)) {
                            width = Math.max(width, getTextWidthForRow(row, mPaints[1]));
                        }
                        row++;
                    }
                    return (MARGIN + width);
                }

                @Override
                public String getCellString(int row) {
                    if (row == -1) {
                        return mActivity.getString(R.string.status);
                    }
                    return String.valueOf(mIterations.get(row).status);
                }
            },
            new ResultsTableAdapter.Column() {
                @Override
                protected int computeWidth() {  
                    return MARGIN + getTextWidth("W", mPaints[0]) +
                        getTextWidthForRow(mIterations.size() - 1, mPaints[0]);
                }


                @Override
                public String getCellString(int row) {
                    if (row == -1) {
                        return mActivity.getString(R.string.latitude);
                    }
                    return String.valueOf(mIterations.get(row).latitide);
                }
            }
            ,
            new ResultsTableAdapter.Column() {
                @Override
                protected int computeWidth() {
                    return MARGIN + getTextWidth("W", mPaints[0]) +
                            getTextWidthForRow(mIterations.size() - 1, mPaints[0]);
                }



                @Override
                public String getCellString(int row) {
                    if (row == -1) {
                        return mActivity.getString(R.string.longitude);
                    }
                    return String.valueOf(mIterations.get(row).longitude);
                }
            }
    };

    public PingAdapter(PingResults results) {
        super(results.iterations.size(), getLayoutInflater());
        mIterations = results.iterations;
        initColumns(columns);
    }
}

private final class SpeedTestAdapter extends ResultsTableAdapter {

    private final List<SpeedTestIteration> mDlIterations;
    private final List<SpeedTestIteration> mUlIterations;
    private final List<SpeedTestIteration> mAllIterations;

    private ResultsTableAdapter.Column[] columns =
            new ResultsTableAdapter.Column[] {
            new ResultsTableAdapter.Column() {
                @SuppressLint("SimpleDateFormat")
                private final DateFormat mDf =
                new SimpleDateFormat("MM-dd HH:mm:ss");

                @Override
                protected int computeWidth() {
                    return MARGIN + getTextWidth("W", mPaints[0]) +
                            getTextWidthForRow(mAllIterations.size() - 1, mPaints[0]);
                }

                @Override
                public String getCellString(int row) {
                    if (row == -1) {
                        return mActivity.getString(R.string.timestamp);
                    }
                    return mDf.format(new Date(mAllIterations.get(row).starttime));
                }
            },
            new ResultsTableAdapter.Column() {
                @Override
                protected int computeWidth() {
                    return MARGIN + getTextWidthForRow(-1, mPaints[0]);
                }

                @Override
                public String getCellString(int row) {
                    final int strId = (row == -1) ? R.string.ftp_dl_ul :
                        row < mDlIterations.size() ? R.string.dl : R.string.ul;
                    return mActivity.getString(strId);
                }
            },
            new ResultsTableAdapter.Column() {
                @Override
                protected int computeWidth() {
                    return MARGIN + getTextWidthForRow(-1, mPaints[0]);
                }

                @Override
                public boolean isColumnRightAligned() {
                    return true;
                }

                @Override
                public String getCellString(int row) {
                    if (row == -1) {
                        return mActivity.getString(R.string.file_size);
                    }
                    return String.valueOf(row < mDlIterations.size() ?
                            mDownloadFileSize : mConfig.ftpFileSize);
                }
            },
            new ResultsTableAdapter.Column() {
                @Override
                protected int computeWidth() {
                    return MARGIN + getTextWidthForRow(-1, mPaints[0]);
                }

                @Override
                public boolean isColumnRightAligned() {
                    return true;
                }

                @SuppressLint("DefaultLocale")
                @Override
                public String getCellString(int row) {
                    if (row == -1) {
                        return mActivity.getString(R.string.avg_throughput);
                    }
                    return String.format("%.3f",
                            mAllIterations.get(row).avgBps * 8 / 1024D);
                }
            },
            new ResultsTableAdapter.Column() {
                @Override
                protected int computeWidth() {
                    int width = getTextWidthForRow(-1, mPaints[0]);
                    int row = 0;

                    for (SpeedTestIteration it : mAllIterations) {
                        if (!"OK".equals(it.status)) {
                            width = Math.max(width, getTextWidthForRow(row, mPaints[1]));
                        }
                        row++;
                    }
                    return (MARGIN + width);
                }

                @Override
                public String getCellString(int row) {
                    if (row == -1) {
                        return mActivity.getString(R.string.status);
                    }
                    return String.valueOf(mAllIterations.get(row).status);
                }
            }
    };

    public SpeedTestAdapter(SpeedTestResult results) {
        super(results.dlResult.iterations.size() + results.ulResult.iterations.size(),
                getLayoutInflater());
        mDlIterations = results.dlResult.iterations;
        mUlIterations = results.ulResult.iterations;
        mAllIterations = new ArrayList<SpeedTestIteration>(
                mDlIterations.size() + mUlIterations.size());
        mAllIterations.addAll(mDlIterations);
        mAllIterations.addAll(mUlIterations);
        initColumns(columns);
    }
}

private final class CallTestAdapter extends ResultsTableAdapter {

    private final List<CallTestIteration> mIterations;

    private ResultsTableAdapter.Column[] columns =
            new ResultsTableAdapter.Column[] {
            new ResultsTableAdapter.Column() {
                @SuppressLint("SimpleDateFormat")
                private final DateFormat mDf =
                new SimpleDateFormat("MM-dd HH:mm:ss");

                @Override
                protected int computeWidth() {
                    return MARGIN + getTextWidth("W", mPaints[0]) +
                            getTextWidthForRow(mIterations.size() - 1, mPaints[0]);
                }

                @Override
                public String getCellString(int row) {
                    if (row == -1) {
                        return mActivity.getString(R.string.timestamp);
                    }
                    return mDf.format(new Date(
                            mIterations.get(row).startTime));
                }
            },
            new ResultsTableAdapter.Column() {
                @Override
                protected int computeWidth() {
                    return MARGIN + getTextWidthForRow(-1, mPaints[0]);
                }

                @Override
                public String getCellString(int row) {
                    if (row == -1) {
                        return mActivity.getString(R.string.called_party_number);
                    }
                    return mConfig.phoneNumber;
                }
            },
            new ResultsTableAdapter.Column() {
                @Override
                protected int computeWidth() {
                    return MARGIN + getTextWidthForRow(-1, mPaints[0]);
                }

                @Override
                public boolean isColumnRightAligned() {
                    return true;
                }

                @Override
                public String getCellString(int row) {
                    if (row == -1) {
                        return mActivity.getString(R.string.call_setup_time);
                    }
                    return String.valueOf(mIterations.get(row).setupTime);
                }
            },
            new ResultsTableAdapter.Column() {
                @Override
                protected int computeWidth() {
                    return MARGIN + getTextWidthForRow(-1, mPaints[0]);
                }

                @Override
                public boolean isColumnRightAligned() {
                    return true;
                }

                @Override
                public String getCellString(int row) {
                    if (row == -1) {
                        return mActivity.getString(R.string.call_duration_s);
                    }
                    return String.valueOf(mIterations.get(row).duration);
                }
            },
            new ResultsTableAdapter.Column() {
                @Override
                protected int computeWidth() {
                    int width = getTextWidthForRow(-1, mPaints[0]);
                    int row = 0;

                    for (CallTestIteration it : mIterations) {
                        if (!CallResult.OK.equals(it.status)) {
                            width = Math.max(width, getTextWidthForRow(row, mPaints[1]));
                        }
                        row++;
                    }
                    return (MARGIN + width);
                }

                @Override
                public String getCellString(int row) {
                    if (row == -1) {
                        return mActivity.getString(R.string.status);
                    }
                    return String.valueOf(mIterations.get(row).status);
                }
            },
            new ResultsTableAdapter.Column() {
                @Override
                protected int computeWidth() {  
                    return MARGIN + getTextWidth("W", mPaints[0]) +
                        getTextWidthForRow(mIterations.size() - 1, mPaints[0]);
                }


                @Override
                public String getCellString(int row) {
                    if (row == -1) {
                        return mActivity.getString(R.string.latitude);
                    }
                    return String.valueOf(mIterations.get(row).latitude);
                }
            }
            ,
            new ResultsTableAdapter.Column() {
                @Override
                protected int computeWidth() {
                    return MARGIN + getTextWidth("W", mPaints[0]) +
                            getTextWidthForRow(mIterations.size() - 1, mPaints[0]);
                }



                @Override
                public String getCellString(int row) {
                    if (row == -1) {
                        return mActivity.getString(R.string.longitude);
                    }
                    return String.valueOf(mIterations.get(row).longitude);
                }
            }

    };

    public CallTestAdapter(CallTestResults results) {
        super(results.iterations.size(), getLayoutInflater());
        mIterations = results.iterations;
        initColumns(columns);
    }
}

@SuppressLint("InflateParams")
private class DetailsExpandableListAdapter extends BaseExpandableListAdapter {

    private List<Results> mResultsList;

    public DetailsExpandableListAdapter(List<Results> resultsList) {
        mResultsList = resultsList;
    }

    @Override
    public Object getChild(int groupPosition, int childPosition) {
        return mResultsList.get(groupPosition);
    }

    @Override
    public long getChildId(int groupPosition, int childPosition) {
        return childPosition;
    }

    @Override
    public View getChildView(int groupPosition, int childPosition,
            boolean isLastChild, View convertView, ViewGroup parent) {
        if (convertView == null) {
            Results results = mResultsList.get(groupPosition);
            final ResultsTableAdapter adapter;

            switch (results.testType) {
           /* case PS_CALL_TEST:
                adapter = new PsCallAdapter((PsCallResults) results);
                break;*/
            case PING_TEST:
                adapter = new PingAdapter((PingResults) results);
                break;
            case SPEED_TEST:
                adapter = new SpeedTestAdapter((SpeedTestResult) results);
                break;
            case CALL_TEST:
                adapter = new CallTestAdapter((CallTestResults) results);
                break;
            default:
                throw new RuntimeException("Invalid result type: " + results.testType);
            }

// Rect rect = new Rect();
// final View tabContent = mActivity.findViewById(android.R.id.tabcontent);
// tabContent.getLocalVisibleRect(rect);

            final TableFixHeaders tableFixHeaders = 
                    (TableFixHeaders) getLayoutInflater().inflate(
                            R.layout.results_table, null);
            tableFixHeaders.setAdapter(adapter);

// tableFixHeaders.setLayoutParams(new AbsListView.LayoutParams(
// LayoutParams.MATCH_PARENT, Math.max(0, rect.height())));
return tableFixHeaders;
}
return convertView;
}

    @Override
    public int getChildrenCount(int groupPosition) {
        return 1;
    }

    @Override
    public TestType getGroup(int groupPosition) {
        return mResultsList.get(groupPosition).testType;
    }

    @Override
    public int getGroupCount() {
        return mResultsList.size();
    }

    @Override
    public long getGroupId(int groupPosition) {
        return groupPosition;
    }

    @SuppressLint("InflateParams")
    @Override
    public View getGroupView(int groupPosition, boolean isExpanded,
            View convertView, ViewGroup parent) {
        TextView textView = (TextView) convertView;
        if (textView == null) {
            textView = (TextView) getLayoutInflater().inflate(
                    R.layout.ongoing_group, null);
        }
        textView.setText(getGroup(groupPosition).toString(mActivity));
        return textView;
    }

    @Override
    public boolean hasStableIds() {
        return true;
    }

    @Override
    public boolean isChildSelectable(int groupPosition, int childPosition) {
        return false;
    }

    @Override
    public int getChildType(int groupPosition, int childPosition) {
        return groupPosition;
    }

    @Override
    public int getChildTypeCount() {
        return mResultsList.size();
    }
}


private class ResultsTableAdapter extends BaseTableAdapter {
    private abstract class Column {

        protected final int MARGIN =
                mActivity.getResources().getDimensionPixelSize(
                        R.dimen.detail_result_cell_margin);
        private int mWidth = -1;
        private Rect mCachedRect = new Rect();

        public int getWidth() {
            if (mWidth == -1) {
                mWidth = computeWidth();
            }
            return mWidth;
        }

        public boolean isColumnRightAligned() {
            return false;
        }

        public abstract String getCellString(int row);

        protected abstract int computeWidth();

        protected int getTextWidthForRow(int row, Paint paint) {
            return getTextWidth(getCellString(row), paint);
        }

        protected int getTextWidth(String text, Paint paint) {
            mCachedRect.setEmpty();
            paint.getTextBounds(text, 0, text.length(), mCachedRect);
            return mCachedRect.right;
        }
    }

    private final int mRowCount;
    private final LayoutInflater mInflater;
    private Paint[] mCachedPaints;
    private FontMetrics mCachedFontMetrics = new FontMetrics();
    private Column[] mColumns = null;

    protected final Paint[] mPaints = new Paint[] {
            getTextPaintForLayoutId(R.layout.cell_header),
            getTextPaintForLayoutId(R.layout.cell_data)
    };

    public ResultsTableAdapter(int rowcount, LayoutInflater inflater) {
        mRowCount = rowcount;
        mInflater = inflater;
        mCachedPaints = new Paint[getViewTypeCount()];
    }

    public void initColumns(Column[] columns) {
        if (mColumns == null) {
            mColumns = columns;
        }
    }

    @Override
    public View getView(int row, int column, View convertView, ViewGroup parent) {

// Log.w("getView: " + row + ", " + column);
if (convertView == null) {
convertView = getView(row, column, parent);
}
setText(convertView, getCellString(row, column));
return convertView;
}

    @Override
    public int getRowCount() {
        return mRowCount;
    }

    @Override
    public int getColumnCount() {
        return mColumns.length;
    }

    @Override
    public int getWidth(int column) {
        return column < 0 ? 0 : mColumns[column].getWidth();
    }

    @Override
    public int getHeight(int row) {
        return getTextHeight(row);
    }

    @Override
    public int getItemViewType(int row, int column) {
        return (row < 0 || column < 0) ? 0 :
            mColumns[column].isColumnRightAligned() ? 2 : 1;
    }

    @Override
    public int getViewTypeCount() {
        return 3;
    }

    private Paint getTextPaintForLayoutId(int id) {
        return ((TextView) getLayoutInflater().inflate(id, null, false)).getPaint();
    }

    private String getCellString(int row, int column) {
        if (column < 0) {
            return "";
        }

        return mColumns[column].getCellString(row);
    }

    private View getView(int row, int column, ViewGroup parent) {
        return mInflater.inflate(getLayoutResource(row, column), parent, false);
    }

    private int getLayoutResource(int row, int column) {
        final int layoutResource;
        switch (getItemViewType(row, column)) {
            case 0:
                layoutResource = R.layout.cell_header;
                break;
            case 1:
                layoutResource = R.layout.cell_data;
                break;
            case 2:
                layoutResource = R.layout.cell_data_align_right;
                break;
            default:
                throw new RuntimeException("Invalid getItemViewType");
        }
        return layoutResource;
    }

    private void setText(View view, String text) {
        ((TextView) view.findViewById(android.R.id.text1)).setText(text);
    }

    private int getTextHeight(int row) {
        getPaint(row).getFontMetrics(mCachedFontMetrics);
        return Math.round(mCachedFontMetrics.bottom - mCachedFontMetrics.top);
    }

    private Paint getPaint(int row) {
        int viewType = getItemViewType(row, 0);
        if (mCachedPaints[viewType] == null) {
            mCachedPaints[viewType] = ((TextView) getView(row, 0, null)).getPaint();
        }
        return mCachedPaints[viewType];
    }
}

}

Not able to view result and getting error,here is my log
uk.co.megrontech.rantcell.ResultsData$ReadDbTask.doInBackground(ResultsData.java:1)
12-05 20:26:07.026 E/CallTest( 9565): at android.os.AsyncTask$2.call(AsyncTask.java:287)
12-05 20:26:07.026 E/CallTest( 9565): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
12-05 20:26:07.026 E/CallTest( 9565): at java.util.concurrent.FutureTask.run(FutureTask.java:137)
12-05 20:26:07.026 E/CallTest( 9565): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
12-05 20:26:07.026 E/CallTest( 9565): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
12-05 20:26:07.026 E/CallTest( 9565): at

Camera is deprecated in android 6.0

Camera is deprecated in android 6.0. I had a issue when I run the application android 6.0 devices. I have received below exception with I open the event,

 java.lang.NullPointerException: Attempt to invoke virtual method 'android.hardware.Camera$Parameters android.hardware.Camera.getParameters()' on a null object reference
                                                     at com.google.android.apps.watchme.VideoFrameGrabber.start(VideoFrameGrabber.java:44)
                                                     at com.google.android.apps.watchme.VideoStreamingConnection.open(VideoStreamingConnection.java:66)
                                                     at com.google.android.apps.watchme.StreamerService.startStreaming(StreamerService.java:72)
                                                     at com.google.android.apps.watchme.StreamerActivity.startStreaming(StreamerActivity.java:211)
                                                     at com.google.android.apps.watchme.StreamerActivity.access$200(StreamerActivity.java:46)
                                                     at com.google.android.apps.watchme.StreamerActivity$1.onServiceConnected(StreamerActivity.java:66)
                                                     at android.app.LoadedApk$ServiceDispatcher.doConnected(LoadedApk.java:1223)
                                                     at android.app.LoadedApk$ServiceDispatcher$RunConnection.run(LoadedApk.java:1240)
                                                     at android.os.Handler.handleCallback(Handler.java:739)
                                                     at android.os.Handler.dispatchMessage(Handler.java:95)
                                                     at android.os.Looper.loop(Looper.java:148)
                                                     at android.app.ActivityThread.main(ActivityThread.java:5417)
                                                     at java.lang.reflect.Method.invoke(Native Method)
                                                     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
                                                     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

How to fix this issue?

Unfortunately, youtube watchme has stopped.

This is the log and can some one help me out.

10-26 16:26:26.820 15200-15235/com.google.android.apps.watchme W/MALI: glDrawArrays:714: [MALI] glDrawArrays takes more than 5ms here. Total elapse time(us): 7016
10-26 16:26:26.875 15200-15200/com.google.android.apps.watchme E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.google.android.apps.watchme, PID: 15200
java.lang.NoSuchMethodError: No virtual method checkSelfPermission(Ljava/lang/String;)I in class Lcom/google/android/apps/watchme/StreamerActivity; or its super classes (declaration of 'com.google.android.apps.watchme.StreamerActivity' appears in /data/data/com.google.android.apps.watchme/files/instant-run/dex/slice-slice_2-classes.dex)
at com.google.android.apps.watchme.StreamerActivity.startStreaming(StreamerActivity.java:174)
at com.google.android.apps.watchme.StreamerActivity.access$200(StreamerActivity.java:46)
at com.google.android.apps.watchme.StreamerActivity$1.onServiceConnected(StreamerActivity.java:66)
at android.app.LoadedApk$ServiceDispatcher.doConnected(LoadedApk.java:1266)
at android.app.LoadedApk$ServiceDispatcher$RunConnection.run(LoadedApk.java:1283)
at android.os.Handler.handleCallback(Handler.java:815)
at android.os.Handler.dispatchMessage(Handler.java:104)
at android.os.Looper.loop(Looper.java:194)
at android.app.ActivityThread.main(ActivityThread.java:5706)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1033)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:828)
10-26 16:26:44.008 15200-15318/com.google.android.apps.watchme E/WatchMe: com.google.api.client.googleapis.json.GoogleJsonResponseException: 403 Forbidden
{
"code": 403,
"errors": [
{
"domain": "youtube.liveBroadcast",
"message": "Stream is inactive",
"reason": "errorStreamInactive",
"extendedHelp": "https://developers.google.com/youtube/v3/live/docs/liveBroadcasts/transition"
}
],
"message": "Stream is inactive"
}
at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:113)
at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:40)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest$1.interceptResponse(AbstractGoogleClientRequest.java:321)
at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:1065)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:419)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:352)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:469)
at com.google.android.apps.watchme.util.YouTubeApi.startEvent(YouTubeApi.java:187)
at com.google.android.apps.watchme.MainActivity$StartEventTask.doInBackground(MainActivity.java:386)
at com.google.android.apps.watchme.MainActivity$StartEventTask.doInBackground(MainActivity.java:371)
at android.os.AsyncTask$2.call(AsyncTask.java:292)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:818)

ffmpeg-jni.c:fps is too low

I'm interesting about live stream with youtube or others.
I have compile ffmpeg to so with the "ffmpeg-jni.c" and it can run with the project
but it not good for user to view,
i think that is about FPS problem, when i use FFMPEG to analysis the stream,
the FPS is only 4~8 fps, How can i do to change the fps, and good for user view?

libavcodec/avcodec.h: No such file or directory

Hi,

When I try to generate the apk, I have the error "libavcodec/avcodec.h: No such file or directory".

I have done what is discribed in
http://www.roman10.net/how-to-build-ffmpeg-with-ndk-r9. So I did all this link said, and now, I have a folder /ffmpeg-2.4.3/android, which contains arm/lib and arm/include folders.

I tried to put these 2 folders in src/main/jni folder (where Android.mk and ffmeg.jni are), but still got the error.

Thank you very much

(I know that I have already asked a similar question in the other threads, and I apologize for that, I do not want to bother all of you)

youtube watchme error

youtube watchme error:

  • I'm able to connect to youtube
  • Its is asking to login with google
  • Once I logged in, shows list of live events,
  • On selecting event, it shows streaming window, then app is getting crashed (Unfortunately, youtube watch me has stopped working ).

This is the error I'm getting
"
10-27 11:24:56.096 30102-30102/com.google.android.apps.watchme E/art: No implementation found for boolean com.google.android.apps.watchme.Ffmpeg.init(int, int, int, java.lang.String) (tried Java_com_google_android_apps_watchme_Ffmpeg_init and Java_com_google_android_apps_watchme_Ffmpeg_init__IIILjava_lang_String_2)
10-27 11:24:56.101 30102-30102/com.google.android.apps.watchme E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.google.android.apps.watchme, PID: 30102
java.lang.UnsatisfiedLinkError: No implementation found for boolean com.google.android.apps.watchme.Ffmpeg.init(int, int, int, java.lang.String) (tried Java_com_google_android_apps_watchme_Ffmpeg_init and Java_com_google_android_apps_watchme_Ffmpeg_init__IIILjava_lang_String_2)
at com.google.android.apps.watchme.Ffmpeg.init(Native Method)
"

Stream is always inactive

After creating a broadcast and start the streaming, I always get ths error caused by calling YouTubeApi.startEvent().

  • Code
Transition transitionRequest = youtube.liveBroadcasts().transition(
                "live", broadcastId, "status");
transitionRequest.execute();
  • Error
com.google.api.client.googleapis.json.GoogleJsonResponseException: 403 Forbidden
    {
    "code": 403,
    "errors": [
    {
    "domain": "youtube.liveBroadcast",
    "message": "Stream is inactive",
    "reason": "errorStreamInactive",
    "extendedHelp": "https://developers.google.com/youtube/v3/live/docs/liveBroadcasts/transition"
    }
    ],
    "message": "Stream is inactive"
    }
            at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:113)
            at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:40)
            at com.google.api.client.googleapis.services.AbstractGoogleClientRequest$1.interceptResponse(AbstractGoogleClientRequest.java:321)
            at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:1056)
            at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:419)
            at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:352)
            at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:469)
            at com.google.android.apps.watchme.util.YouTubeApi.startEvent(YouTubeApi.java:187)
            at com.google.android.apps.watchme.MainActivity$StartEventTask.doInBackground(MainActivity.java:389)
            at com.google.android.apps.watchme.MainActivity$StartEventTask.doInBackground(MainActivity.java:374)
            at android.os.AsyncTask$2.call(AsyncTask.java:288)
            at java.util.concurrent.FutureTask.run(FutureTask.java:237)
            at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
            at java.lang.Thread.run(Thread.java:818)

How can I fix this problem??

Youtue Watch Me Android application closing unexpectedly

I created live streaming application using https://github.com/youtube/yt-watchme. And its installed on android phone.If I logged into this app.I's still shows the "Not Signed in" Message. After login its showing the following error in android studio console

09-16 16:48:01.970 25937-3107/com.google.android.apps.watchme E/WatchMe﹕ com.google.api.client.googleapis.json.GoogleJsonResponseException: 403 Forbidden
{
"code": 403,
"errors": [
{
"domain": "usageLimits",
"message": "Access Not Configured. The API (YouTube Data API) is not enabled for your project. Please use the Google Developers Console to update your configuration.",
"reason": "accessNotConfigured",
"extendedHelp": "https://console.developers.google.com"
}
],
"message": "Access Not Configured. The API (YouTube Data API) is not enabled for your project. Please use the Google Developers Console to update your configuration."
}
at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:113)
at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:40)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest$1.interceptResponse(AbstractGoogleClientRequest.java:321)
at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:1056)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:419)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:352)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:469)
at com.google.android.apps.watchme.util.YouTubeApi.getLiveEvents(YouTubeApi.java:155)
at com.google.android.apps.watchme.MainActivity$GetLiveEventsTask.doInBackground(MainActivity.java:312)
at com.google.android.apps.watchme.MainActivity$GetLiveEventsTask.doInBackground(MainActivity.java:295)
at android.os.AsyncTask$2.call(AsyncTask.java:288)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:841)

How can i solve this issue please help.

This application is connecting to YouTube Watch Me project.Is it possible to connect my project using client Id and client secret(How can i configure my client id to this app?)?

Please suggest

Please help me to use this project with eclipse

Hi,
I'm newbie with developing on android app.
Now, I want to make an application that can record and upload to my youtube account.
But, when I download the zip file and import with Eclipse (select option for Gradle Project).
Then when I press "build model", eclipse inform me an error in console log:

*FAILURE: Build failed with an exception.

  • Where:
    *Build file '/Users/PhienTram/Downloads/yt-watchme-master/app/build.gradle' line: 18

  • What went wrong:
    A problem occurred evaluating project ':app'.

    Ambiguous method overloading for method java.io.File#.
    Cannot resolve which method to invoke for [null, class java.lang.String] due to overlapping prototypes between:
    [class java.lang.String, class java.lang.String]
    [class java.io.File, class java.lang.String]

  • Try:
    Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
    So, can you help me to run it out.

Thanks and Best Regards

java.lang.UnsatisfiedLinkError .android.apps.watchme.Ffmpeg.init

Hi their ,
Upon implementing the api for live streaming I came across the following issue/ error would be of huge help if any of you could suggest me a solution.

java.lang.UnsatisfiedLinkError: No implementation found for boolean com.google.android.apps.watchme.Ffmpeg.init(int, int, int, java.lang.String) (tried Java_com_google_android_apps_watchme_Ffmpeg_init and Java_com_google_android_apps_watchme_Ffmpeg_init__IIILjava_lang_String_2)
at com.google.android.apps.watchme.Ffmpeg.init(Native Method)
at com.google.android.apps.watchme.VideoStreamingConnection.open(VideoStreamingConnection.java:71)
at com.google.android.apps.watchme.StreamerService.startStreaming(StreamerService.java:72)
at com.google.android.apps.watchme.StreamerActivity.startStreaming(StreamerActivity.java:210)
at com.google.android.apps.watchme.StreamerActivity.access$200(StreamerActivity.java:47)
at com.google.android.apps.watchme.StreamerActivity$1.onServiceConnected(StreamerActivity.java:67)
at android.app.LoadedApk$ServiceDispatcher.doConnected(LoadedApk.java:1208)
at android.app.LoadedApk$ServiceDispatcher$RunConnection.run(LoadedApk.java:1225)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5343)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:905)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:700)

137213de-e458-11e5-9cc6-6114b8f4e8fc

and Cannot resolve corresponding JNI function Java_com_google_android_apps_watchme_Ffmpeg_init less.
Reports native method declarations in Java where no corresponding JNI function is found in the project.

d50738a2-e45e-11e5-88cb-f7c7a766da75

The yt-watchme project is not for live stream?

The yt-watchme project I tried to make it work on my ANDROID device has a lag(or latency) of almost ~1min.

If I start live stream from my device, the video at youtube events site will remain idle(shows black screen with the title.) for about a minute and then it will start streaming the 1 minute old data to the youtube site.

And the process continues,

1.) the video will always be 1 minute late.
2.) the speed of the video is very fast by default.
3.) the audio will not work, even after compiling the lame according to the provided Android.mk file.
4.) is there anyway to @iulukaya to prove that this his project is worth the title of live streaming?

I am not asking for the code, but how to make the live stream possible with this small application.

Login is not happening and also showing some error

Hi,

I run this app in my android phone. After my login It's still showing "Not signed In" message.When i click one the "CREATE LIVE EVENT" .it's show some error in android studio console

Error Message:

{
"code": 403,
"errors": [
{
"domain": "usageLimits",
"message": "Access Not Configured. The API (YouTube Data API) is not enabled for your project. Please use the Google Developers Console to update your configuration.",
"reason": "accessNotConfigured",
"extendedHelp": "https://console.developers.google.com"
}
],
"message": "Access Not Configured. The API (YouTube Data API) is not enabled for your project. Please use the Google Developers Console to update your configuration."
}

Where I can configure my app client id and client secret for this app?

liveBroadcast's status is always null

After ctreating a liveBroadCast and a liveStream,found liveBroadCast's status is always null,why?
After binding to a liveStream,the status value is null too.

Java.Lang.UnSatisfiedLinkError Native Method not found in Android Studio in Windows

I used Youtube watch me source code into my own project. but I got the error. I changed the package name in ffmpeg-jni.c.

03-23 18:11:03.990 308-308/com.ephron.mobilizerapp E/AndroidRuntime: FATAL EXCEPTION: main Process: com.ephron.mobilizerapp, PID: 308 java.lang.UnsatisfiedLinkError: Native method not found: com.ephronsystem.mobilizerapp.Ffmpeg.init:(IIILjava/lang/String;)Z at com.ephronsystem.mobilizerapp.Ffmpeg.init(Native Method) at com.ephronsystem.mobilizerapp.VideoStreamingConnection.open(VideoStreamingConnection.java:79) at com.ephronsystem.mobilizerapp.MobilizationFeatures$StartEventTask.onPostExecute(MobilizationFeatures.java:3106) at com.ephronsystem.mobilizerapp.MobilizationFeatures$StartEventTask.onPostExecute(MobilizationFeatures.java:3076) at android.os.AsyncTask.finish(AsyncTask.java:632) at android.os.AsyncTask.access$600(AsyncTask.java:177) at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:645) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:146) at android.app.ActivityThread.main(ActivityThread.java:5602) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:515) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1283) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1099) at dalvik.system.NativeStart.main(Native Method)

r

`#include <android/log.h>
#include <string.h>
#include <jni.h>

#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libavutil/opt.h"

#ifdef __cplusplus
extern "C" {
#endif

JNIEXPORT jboolean JNICALL Java_com_ephronsystem_mobilizerapp_Ffmpeg_init(JNIEnv *env, jobject thiz, jint width, jint height, jint audio_sample_rate, jstring rtmp_url);
JNIEXPORT void JNICALL Java_com_ephronsystem_mobilizerapp_Ffmpeg_shutdown(JNIEnv *env, jobject thiz);
JNIEXPORT jint JNICALL Java_com_ephronsystem_mobilizerapp_Ffmpeg_encodeVideoFrame(JNIEnv *env, jobject thiz, jbyteArray yuv_image);
JNIEXPORT jint JNICALL Java_com_ephronsystem_mobilizerapp_Ffmpeg_encodeAudioFrame(JNIEnv *env, jobject thiz, jshortArray audio_data, jint length);

#ifdef __cplusplus
}
#endif

#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, "ffmpeg-jni", VA_ARGS)
#define URL_WRONLY 2
static AVFormatContext *fmt_context;
static AVStream *video_stream;
static AVStream *audio_stream;

static int pts = 0;
static int last_audio_pts = 0;

// Buffers for UV format conversion
static unsigned char *u_buf;
static unsigned char *v_buf;

static int enable_audio = 1;
static int64_t audio_samples_written = 0;
static int audio_sample_rate = 0;

// Stupid buffer for audio samples. Not even a proper ring buffer
#define AUDIO_MAX_BUF_SIZE 16384 // 2x what we get from Java
static short audio_buf[AUDIO_MAX_BUF_SIZE];
static int audio_buf_size = 0;
void AudioBuffer_Push(const short *audio, int num_samples) {
if (audio_buf_size >= AUDIO_MAX_BUF_SIZE - num_samples) {
LOGI("AUDIO BUFFER OVERFLOW: %i + %i > %i", audio_buf_size, num_samples, AUDIO_MAX_BUF_SIZE);
return;
}
for (int i = 0; i < num_samples; i++) {
audio_buf[audio_buf_size++] = audio[i];
}
}
int AudioBuffer_Size() { return audio_buf_size; }
short *AudioBuffer_Get() { return audio_buf; }
void AudioBuffer_Pop(int num_samples) {
if (num_samples > audio_buf_size) {
LOGI("Audio buffer Pop WTF: %i vs %i", num_samples, audio_buf_size);
return;
}
memmove(audio_buf, audio_buf + num_samples, num_samples * sizeof(short));
audio_buf_size -= num_samples;
}
void AudioBuffer_Clear() {
memset(audio_buf, 0, sizeof(audio_buf));
audio_buf_size = 0;
}

static void log_callback(void* ptr, int level, const char* fmt, va_list vl) {
char x[2048];
vsnprintf(x, 2048, fmt, vl);
// LOGI(x);
LOGI("%s", x);
}

JNIEXPORT jboolean JNICALL Java_com_ephronsystem_mobilizerapp_Ffmpeg_init(JNIEnv *env, jobject thiz, jint width, jint height, jint audio_sample_rate_param, jstring rtmp_url) {
avcodec_register_all();
av_register_all();
av_log_set_callback(log_callback);

fmt_context = avformat_alloc_context();
AVOutputFormat *ofmt = av_guess_format("flv", NULL, NULL);
if (ofmt) {
LOGI("av_guess_format returned %s", ofmt->long_name);
} else {
LOGI("av_guess_format fail");
return JNI_FALSE;
}

fmt_context->oformat = ofmt;
LOGI("creating video stream");
video_stream = av_new_stream(fmt_context, 0);
//GS ? video_stream = avformat_new_stream(fmt_context, 0);

if (enable_audio) {
LOGI("creating audio stream");
audio_stream = av_new_stream(fmt_context, 1);
//GS ? audio_stream = avformat_new_stream(fmt_context, 1);
LOGI("creating audio stream OK ?");
}

// Open Video Codec.
// ======================

LOGI("B4 avcodec_find_encoder(AV_CODEC_ID_H264)");

AVCodec *video_codec = avcodec_find_encoder(AV_CODEC_ID_H264);
if (!video_codec) {
LOGI("Did not find the video codec");
return JNI_FALSE; // leak!
} else {
LOGI("Video codec found!");
}

/*

  • Encoder settings

Protocol: RTMP Flash Streaming
Video codec: H.264, 4.1
Frame rate: up to 60 fps
Keyframe frequency: do not exceed 4 seconds
Audio codec: AAC or MP3
Bitrate encoding: CBR
Recommended advanced settings

Pixel aspect ratio: Square
Frame types: Progressive Scan, 2 B-Frames, 1 Reference Frame
Entropy coding: CABAC
Audio sample rate: 44.1 KHz
Audio bitrate: 128 Kbps stereo

*/

AVCodecContext *video_codec_ctx = video_stream->codec;
video_codec_ctx->codec_id = video_codec->id;
video_codec_ctx->codec_type = AVMEDIA_TYPE_VIDEO;
video_codec_ctx->level = 31;

video_codec_ctx->width = width;
video_codec_ctx->height = height;
video_codec_ctx->pix_fmt = PIX_FMT_YUV420P;
video_codec_ctx->rc_max_rate = 0;
video_codec_ctx->rc_buffer_size = 0;
video_codec_ctx->gop_size = 12;
video_codec_ctx->max_b_frames = 0;
video_codec_ctx->slices = 8;
video_codec_ctx->b_frame_strategy = 1;
video_codec_ctx->coder_type = 0;
video_codec_ctx->me_cmp = 1;
video_codec_ctx->me_range = 16;
video_codec_ctx->qmin = 10;
video_codec_ctx->qmax = 51;
video_codec_ctx->keyint_min = 25;
video_codec_ctx->refs= 3;
video_codec_ctx->trellis = 0;
video_codec_ctx->scenechange_threshold = 40;
video_codec_ctx->flags |= CODEC_FLAG_LOOP_FILTER;
video_codec_ctx->me_method = ME_HEX;
video_codec_ctx->me_subpel_quality = 6;
video_codec_ctx->i_quant_factor = 0.71;
video_codec_ctx->qcompress = 0.6;
video_codec_ctx->max_qdiff = 4;
video_codec_ctx->time_base.den = 10;
video_codec_ctx->time_base.num = 1;
video_codec_ctx->bit_rate = 3200*1000;
video_codec_ctx->bit_rate_tolerance = 0;
video_codec_ctx->flags2 |= 0x00000100;

fmt_context->bit_rate = 4000*1000;

av_opt_set(video_codec_ctx, "partitions", "i8x8,i4x4,p8x8,b8x8", 0);
av_opt_set_int(video_codec_ctx, "direct-pred", 1, 0);
av_opt_set_int(video_codec_ctx, "rc-lookahead", 0, 0);
av_opt_set_int(video_codec_ctx, "fast-pskip", 1, 0);
av_opt_set_int(video_codec_ctx, "mixed-refs", 1, 0);
av_opt_set_int(video_codec_ctx, "8x8dct", 0, 0);
av_opt_set_int(video_codec_ctx, "weightb", 0, 0);

if(fmt_context->oformat->flags & AVFMT_GLOBALHEADER)
video_codec_ctx->flags |= CODEC_FLAG_GLOBAL_HEADER;

LOGI("Opening video codec");
AVDictionary *vopts = NULL;
av_dict_set(&vopts, "profile", "main", 0);
//av_dict_set(&vopts, "vprofile", "main", 0);
av_dict_set(&vopts, "rc-lookahead", 0, 0);
av_dict_set(&vopts, "tune", "film", 0);
av_dict_set(&vopts, "preset", "ultrafast", 0);
av_opt_set(video_codec_ctx->priv_data,"tune","film",0);
av_opt_set(video_codec_ctx->priv_data,"preset","ultrafast",0);
av_opt_set(video_codec_ctx->priv_data,"tune","film",0);
int open_res = avcodec_open2(video_codec_ctx, video_codec, &vopts);
if (open_res < 0) {
LOGI("Error opening video codec: %i", open_res);
return JNI_FALSE; // leak!
}

// Open Audio Codec.
// ======================

if (enable_audio) {
AudioBuffer_Clear();
audio_sample_rate = audio_sample_rate_param;
AVCodec *audio_codec = avcodec_find_encoder(AV_CODEC_ID_AAC);
if (!audio_codec) {
LOGI("Did not find the audio codec");
return JNI_FALSE; // leak!
} else {
LOGI("Audio codec found!");
}
AVCodecContext *audio_codec_ctx = audio_stream->codec;
audio_codec_ctx->codec_id = audio_codec->id;
audio_codec_ctx->codec_type = AVMEDIA_TYPE_AUDIO;
audio_codec_ctx->bit_rate = 128000;
audio_codec_ctx->bit_rate_tolerance = 16000;
audio_codec_ctx->channels = 1;

audio_codec_ctx->profile = FF_PROFILE_AAC_LOW;
//GS NBG !!! audio_codec_ctx->profile = AV_CODEC_ID_MP3;

audio_codec_ctx->sample_fmt = AV_SAMPLE_FMT_FLT;
audio_codec_ctx->sample_rate = 44100;

LOGI("Opening audio codec");
AVDictionary *opts = NULL;
av_dict_set(&opts, "strict", "experimental", 0);
open_res = avcodec_open2(audio_codec_ctx, audio_codec, &opts);
LOGI("audio frame size: %i", audio_codec_ctx->frame_size);

if (open_res < 0) {
  LOGI("Error opening audio codec: %i", open_res);
  return JNI_FALSE;   // leak!
}

}

const jbyte *url = (*env)->GetStringUTFChars(env, rtmp_url, NULL);

// Point to an output file
if (!(ofmt->flags & AVFMT_NOFILE)) {
if (avio_open(&fmt_context->pb, url, URL_WRONLY) < 0) {
LOGI("ERROR: Could not open file %s", url);
return JNI_FALSE; // leak!
}
}
(*env)->ReleaseStringUTFChars(env, rtmp_url, url);

LOGI("Writing output header.");
// Write file header
if (avformat_write_header(fmt_context, NULL) != 0) {
LOGI("ERROR: av_write_header failed");
return JNI_FALSE;
}

pts = 0;
last_audio_pts = 0;
audio_samples_written = 0;

// Initialize buffers for UV format conversion
int frame_size = video_codec_ctx->width * video_codec_ctx->height;
u_buf = (unsigned char *)av_malloc(frame_size / 4);
v_buf = (unsigned char *)av_malloc(frame_size / 4);

LOGI("ffmpeg encoding init done");
return JNI_TRUE;
}

JNIEXPORT void JNICALL Java_com_ephronsystem_mobilizerapp_Ffmpeg_shutdown(JNIEnv *env, jobject thiz) {
av_write_trailer(fmt_context);
avio_close(fmt_context->pb);
avcodec_close(video_stream->codec);
if (enable_audio) {
avcodec_close(audio_stream->codec);
}
av_free(fmt_context);
av_free(u_buf);
av_free(v_buf);

fmt_context = NULL;
u_buf = NULL;
v_buf = NULL;
}

JNIEXPORT jint JNICALL Java_com_ephronsystem_mobilizerapp_Ffmpeg_encodeVideoFrame(JNIEnv *env, jobject thiz, jbyteArray yuv_image) {
int yuv_length = (*env)->GetArrayLength(env, yuv_image);
unsigned char *yuv_data = (*env)->GetByteArrayElements(env, yuv_image, 0);

AVCodecContext *video_codec_ctx = video_stream->codec;
//LOGI("Yuv size: %i w: %i h: %i", yuv_length, video_codec_ctx->width, video_codec_ctx->height);

int frame_size = video_codec_ctx->width * video_codec_ctx->height;

const unsigned char *uv = yuv_data + frame_size;

// Convert YUV from NV12 to I420. Y channel is the same so we don't touch it,
// we just have to deinterleave UV.
for (int i = 0; i < frame_size / 4; i++) {
v_buf[i] = uv[i * 2];
u_buf[i] = uv[i * 2 + 1];
}

AVFrame source;
memset(&source, 0, sizeof(AVFrame));
source.data[0] = yuv_data;
source.data[1] = u_buf;
source.data[2] = v_buf;
source.linesize[0] = video_codec_ctx->width;
source.linesize[1] = video_codec_ctx->width / 2;
source.linesize[2] = video_codec_ctx->width / 2;

// only for bitrate regulation. irrelevant for sync.
source.pts = pts;
pts++;

int out_length = frame_size + (frame_size / 2);
unsigned char *out = (unsigned char *) av_malloc(out_length);
int compressed_length = avcodec_encode_video(video_codec_ctx, out, out_length, &source);

(*env)->ReleaseByteArrayElements(env, yuv_image, yuv_data, 0);

// Write to file too
if (compressed_length > 0) {
AVPacket pkt;
av_init_packet(&pkt);
pkt.pts = last_audio_pts;
if (video_codec_ctx->coded_frame && video_codec_ctx->coded_frame->key_frame) {
pkt.flags |= 0x0001;
}
pkt.stream_index = video_stream->index;
pkt.data = out;
pkt.size = compressed_length;
if (av_interleaved_write_frame(fmt_context, &pkt) != 0) {
LOGI("Error writing video frame");
}
} else {
LOGI("??? compressed_length <= 0");
}

last_audio_pts++;

av_free(out);
return compressed_length;
}

JNIEXPORT jint JNICALL Java_com_ephronsystem_mobilizerapp_Ffmpeg_encodeAudioFrame(JNIEnv *env, jobject thiz, jshortArray audio_data, jint length) {
if (!enable_audio) {
return 0;
}

short *audio = (*env)->GetShortArrayElements(env, audio_data, 0);
//LOGI("java audio buffer size: %i", length);

AVCodecContext *audio_codec_ctx = audio_stream->codec;

unsigned char *out = av_malloc(128000);

AudioBuffer_Push(audio, length);

int total_compressed = 0;
while (AudioBuffer_Size() >= audio_codec_ctx->frame_size) {
AVPacket pkt;
av_init_packet(&pkt);

int compressed_length = avcodec_encode_audio(audio_codec_ctx, out, 128000, AudioBuffer_Get());

total_compressed += compressed_length;
audio_samples_written += audio_codec_ctx->frame_size;

int new_pts = (audio_samples_written * 1000) / audio_sample_rate;
if (compressed_length > 0) {
  pkt.size = compressed_length;
  pkt.pts = new_pts;
  last_audio_pts = new_pts;
  //LOGI("audio_samples_written: %i  comp_length: %i   pts: %i", (int)audio_samples_written, (int)compressed_length, (int)new_pts);
  pkt.flags |= 0x0001;
  pkt.stream_index = audio_stream->index;
  pkt.data = out;
  if (av_interleaved_write_frame(fmt_context, &pkt) != 0) {
    LOGI("Error writing audio frame");
  }
}
AudioBuffer_Pop(audio_codec_ctx->frame_size);

}

(*env)->ReleaseShortArrayElements(env, audio_data, audio, 0);

av_free(out);
return total_compressed;
}
`

I can't add tags to the new event created

I am trying to create a live event with tags, however, the BroadcastSnippet class doesn't contain a tags field. Does anyone know how I can add tags to a new live event?

Audio & video issue

Able to stream video.

Video was blur and audio was not proper, how to fix this?

Switch cameras

Is there an easy way to switch cameras while streaming? Trial and error shows that changing out the camera in preview and in the streaming service is not connecting it to the screen. Seems like there are a lot of camera objects laying around - Preview, StreamerService, VideoFrameGrabber. Which Camera is going to the screen (VideoFrameGrabber?) and what's the best, most efficient mobile friendly way to change it without leaking resources or crashing the app?

WatchMe project throws error at Runtime

I imported this project in eclipse. But when I click on "CREATE LIVE EVENT" button it gets crashed. This is the line where it gets crashed.

  YouTube youtube = new YouTube.Builder(transport, jsonFactory,
            credential).setApplicationName(APP_NAME)
            .build();

See log below:

02-02 14:48:20.764: E/AndroidRuntime(25875): FATAL EXCEPTION: AsyncTask #1
02-02 14:48:20.764: E/AndroidRuntime(25875): java.lang.RuntimeException: An error occured while executing doInBackground()
02-02 14:48:20.764: E/AndroidRuntime(25875): at android.os.AsyncTask$3.done(AsyncTask.java:299)
02-02 14:48:20.764: E/AndroidRuntime(25875): at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:352)
02-02 14:48:20.764: E/AndroidRuntime(25875): at java.util.concurrent.FutureTask.setException(FutureTask.java:219)
02-02 14:48:20.764: E/AndroidRuntime(25875): at java.util.concurrent.FutureTask.run(FutureTask.java:239)
02-02 14:48:20.764: E/AndroidRuntime(25875): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
02-02 14:48:20.764: E/AndroidRuntime(25875): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
02-02 14:48:20.764: E/AndroidRuntime(25875): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
02-02 14:48:20.764: E/AndroidRuntime(25875): at java.lang.Thread.run(Thread.java:856)
02-02 14:48:20.764: E/AndroidRuntime(25875): Caused by: java.lang.NullPointerException
02-02 14:48:20.764: E/AndroidRuntime(25875): at com.google.android.apps.watchme.util.YouTubeApi.getLiveEvents(YouTubeApi.java:150)
02-02 14:48:20.764: E/AndroidRuntime(25875): at com.example.watchme.MainActivity$CreateLiveEventTask.doInBackground(MainActivity.java:361)
02-02 14:48:20.764: E/AndroidRuntime(25875): at com.example.watchme.MainActivity$CreateLiveEventTask.doInBackground(MainActivity.java:1)
02-02 14:48:20.764: E/AndroidRuntime(25875): at android.os.AsyncTask$2.call(AsyncTask.java:287)
02-02 14:48:20.764: E/AndroidRuntime(25875): at java.util.concurrent.FutureTask.run(FutureTask.java:234)
02-02 14:48:20.764: E/AndroidRuntime(25875): ... 4 more

I tried to solve this error by importing different JARs but was unable to solve it. Can anyone please help me for this?

src/main/jni/libavutil/float_dsp.h:148:50: error: expected ';', ',' or ')' before 'v1'

Built ffmpeg, ran the ndk, updated JNI codes, and on finally compiling, the following error comes up -

src/main/jni/libavutil/float_dsp.h:148:50: error: expected ';', ',' or ')' before 'v1'
make: *** [.../AndroidstudioProjects/yt-watchme-master/app/build/intermediates/ndk/debug/obj/local/armeabi-v7a/objs/app//Users/Karthik/AndroidstudioProjects/yt-watchme-master/app/src/main/jni/libavutil/arm/float_dsp_init_arm.o] Error 1

Have been stuck on this problem for ages. Help would be greatly appreciated.

Error:executing external native build for ndkBuild E:\A-Android\yt-watchme-master\app\src\main\jni\Android.mk

Help me, I try build but don't and error:

External Native Build Issues
Build command failed.
Error while executing 'C:\Users\Akashjpro\AppData\Local\Android\Sdk\ndk-bundle\ndk-build.cmd' with arguments {NDK_PROJECT_PATH=null APP_BUILD_SCRIPT=E:\A-Android\yt-watchme-master\app\src\main\jni\Android.mk APP_ABI=armeabi NDK_ALL_ABIS=armeabi NDEBUG=0 APP_PLATFORM=android-16 NDK_OUT=E:/A-Android/yt-watchme-master/app/build/intermediates/ndkBuild/release/obj NDK_LIBS_OUT=E:\A-Android\yt-watchme-master\app\build\intermediates\ndkBuild\release\lib APP_SHORT_COMMANDS=false LOCAL_SHORT_COMMANDS=false -n}
Android NDK: WARNING:E:\A-Android\yt-watchme-master\app\src\main\jni\Android.mk:ffmpeg: non-system libraries in linker flags: E:/A-Android/yt-watchme-master/app/src/main/jni/../third_party/lib/libavformat.a E:/A-Android/yt-watchme-master/app/src/main/jni/../third_party/lib/libavcodec.a E:/A-Android/yt-watchme-master/app/src/main/jni/../third_party/lib/libavfilter.a E:/A-Android/yt-watchme-master/app/src/main/jni/../third_party/lib/libavresample.a E:/A-Android/yt-watchme-master/app/src/main/jni/../third_party/lib/libswscale.a E:/A-Android/yt-watchme-master/app/src/main/jni/../third_party/lib/libavutil.a E:/A-Android/yt-watchme-master/app/src/main/jni/../third_party/lib/libx264.a E:/A-Android/yt-watchme-master/app/src/main/jni/../third_party/lib/libpostproc.a E:/A-Android/yt-watchme-master/app/src/main/jni/../third_party/lib/libswresample.a E:/A-Android/yt-watchme-master/app/src/main/jni/../third_party/lib/libfdk-aac.a
Android NDK: This is likely to result in incorrect builds. Try using LOCAL_STATIC_LIBRARIES
Android NDK: or LOCAL_SHARED_LIBRARIES instead to list the library dependencies of the
Android NDK: current module
md "E:\A-Android\yt-watchme-master\app\build\intermediates\ndkBuild\release\obj\local\armeabi\objs\ffmpeg" >NUL 2>NUL || rem
C:/Users/Akashjpro/AppData/Local/Android/sdk/ndk-bundle/build//../prebuilt/windows-x86_64/bin/echo.exe [armeabi] "Compile thumb ": "ffmpeg <= ffmpeg-jni.c"
C:/Users/Akashjpro/AppData/Local/Android/sdk/ndk-bundle/build//../toolchains/llvm/prebuilt/windows-x86_64/bin/clang.exe -MMD -MP -MF E:/A-Android/yt-watchme-master/app/build/intermediates/ndkBuild/release/obj/local/armeabi/objs/ffmpeg/ffmpeg-jni.o.d -gcc-toolchain C:/Users/Akashjpro/AppData/Local/Android/sdk/ndk-bundle/build//../toolchains/arm-linux-androideabi-4.9/prebuilt/windows-x86_64 -fpic -ffunction-sections -funwind-tables -fstack-protector-strong -Wno-invalid-command-line-argument -Wno-unused-command-line-argument -no-canonical-prefixes -fno-integrated-as -g -target armv5te-none-linux-androideabi -march=armv5te -mtune=xscale -msoft-float -mthumb -Os -DNDEBUG -IE:/A-Android/yt-watchme-master/app/src/main/jni/../third_party/include -IE:/A-Android/yt-watchme-master/app/src/main/jni -DANDROID -DHAVE_AV_CONFIG_H -std=c99 -D__STDC_CONSTANT_MACROS -DSTDC_HEADERS -Wa,--noexecstack -Wformat -Werror=format-security -isystem C:/Users/Akashjpro/AppData/Local/Android/sdk/ndk-bundle/build//../platforms/android-16/arch-arm/usr/include -c E:/A-Android/yt-watchme-master/app/src/main/jni/ffmpeg-jni.c -o E:/A-Android/yt-watchme-master/app/build/intermediates/ndkBuild/release/obj/local/armeabi/objs/ffmpeg/ffmpeg-jni.o
md "E:\A-Android\yt-watchme-master\app\build\intermediates\ndkBuild\release\obj\local\armeabi" >NUL 2>NUL || rem
process_begin: CreateProcess(NULL, "", ...) failed.
make: *** No rule to make target E:/A-Android/yt-watchme-master/app/src/main/jni/../third_party/lame/libmp3lame/VbrTag.c', needed by E:/A-Android/yt-watchme-master/app/build/intermediates/ndkBuild/release/obj/local/armeabi/objs/lame/VbrTag.o'. Stop.
Error:executing external native build for ndkBuild E:\A-Android\yt-watchme-master\app\src\main\jni\Android.mk
Build command failed.
Error while executing 'C:\Users\Akashjpro\AppData\Local\Android\Sdk\ndk-bundle\ndk-build.cmd' with arguments {NDK_PROJECT_PATH=null APP_BUILD_SCRIPT=E:\A-Android\yt-watchme-master\app\src\main\jni\Android.mk APP_ABI=armeabi NDK_ALL_ABIS=armeabi NDEBUG=1 APP_PLATFORM=android-16 NDK_OUT=E:/A-Android/yt-watchme-master/app/build/intermediates/ndkBuild/debug/obj NDK_LIBS_OUT=E:\A-Android\yt-watchme-master\app\build\intermediates\ndkBuild\debug\lib APP_SHORT_COMMANDS=false LOCAL_SHORT_COMMANDS=false -n}
Android NDK: WARNING:E:\A-Android\yt-watchme-master\app\src\main\jni\Android.mk:ffmpeg: non-system libraries in linker flags: E:/A-Android/yt-watchme-master/app/src/main/jni/../third_party/lib/libavformat.a E:/A-Android/yt-watchme-master/app/src/main/jni/../third_party/lib/libavcodec.a E:/A-Android/yt-watchme-master/app/src/main/jni/../third_party/lib/libavfilter.a E:/A-Android/yt-watchme-master/app/src/main/jni/../third_party/lib/libavresample.a E:/A-Android/yt-watchme-master/app/src/main/jni/../third_party/lib/libswscale.a E:/A-Android/yt-watchme-master/app/src/main/jni/../third_party/lib/libavutil.a E:/A-Android/yt-watchme-master/app/src/main/jni/../third_party/lib/libx264.a E:/A-Android/yt-watchme-master/app/src/main/jni/../third_party/lib/libpostproc.a E:/A-Android/yt-watchme-master/app/src/main/jni/../third_party/lib/libswresample.a E:/A-Android/yt-watchme-master/app/src/main/jni/../third_party/lib/libfdk-aac.a
Android NDK: This is likely to result in incorrect builds. Try using LOCAL_STATIC_LIBRARIES
Android NDK: or LOCAL_SHARED_LIBRARIES instead to list the library dependencies of the
Android NDK: current module
md "E:\A-Android\yt-watchme-master\app\build\intermediates\ndkBuild\debug\obj\local\armeabi\objs\ffmpeg" >NUL 2>NUL || rem
C:/Users/Akashjpro/AppData/Local/Android/sdk/ndk-bundle/build//../prebuilt/windows-x86_64/bin/echo.exe [armeabi] "Compile thumb ": "ffmpeg <= ffmpeg-jni.c"
C:/Users/Akashjpro/AppData/Local/Android/sdk/ndk-bundle/build//../toolchains/llvm/prebuilt/windows-x86_64/bin/clang.exe -MMD -MP -MF E:/A-Android/yt-watchme-master/app/build/intermediates/ndkBuild/debug/obj/local/armeabi/objs/ffmpeg/ffmpeg-jni.o.d -gcc-toolchain C:/Users/Akashjpro/AppData/Local/Android/sdk/ndk-bundle/build//../toolchains/arm-linux-androideabi-4.9/prebuilt/windows-x86_64 -fpic -ffunction-sections -funwind-tables -fstack-protector-strong -Wno-invalid-command-line-argument -Wno-unused-command-line-argument -no-canonical-prefixes -fno-integrated-as -g -target armv5te-none-linux-androideabi -march=armv5te -mtune=xscale -msoft-float -mthumb -Os -DNDEBUG -IE:/A-Android/yt-watchme-master/app/src/main/jni/../third_party/include -IE:/A-Android/yt-watchme-master/app/src/main/jni -DANDROID -DHAVE_AV_CONFIG_H -std=c99 -D__STDC_CONSTANT_MACROS -DSTDC_HEADERS -Wa,--noexecstack -Wformat -Werror=format-security -isystem C:/Users/Akashjpro/AppData/Local/Android/sdk/ndk-bundle/build//../platforms/android-16/arch-arm/usr/include -c E:/A-Android/yt-watchme-master/app/src/main/jni/ffmpeg-jni.c -o E:/A-Android/yt-watchme-master/app/build/intermediates/ndkBuild/debug/obj/local/armeabi/objs/ffmpeg/ffmpeg-jni.o
md "E:\A-Android\yt-watchme-master\app\build\intermediates\ndkBuild\debug\obj\local\armeabi" >NUL 2>NUL || rem
process_begin: CreateProcess(NULL, "", ...) failed.
make: *** No rule to make target E:/A-Android/yt-watchme-master/app/src/main/jni/../third_party/lame/libmp3lame/VbrTag.c', needed by E:/A-Android/yt-watchme-master/app/build/intermediates/ndkBuild/debug/obj/local/armeabi/objs/lame/VbrTag.o'. Stop.
Error:executing external native build for ndkBuild E:\A-Android\yt-watchme-master\app\src\main\jni\Android.mk
E:\A-Android\yt-watchme-master\app\build.gradle
Warning:WARNING: Dependency org.apache.httpcomponents:httpclient:4.0.1 is ignored for release as it may be conflicting with the internal version provided by Android.
In case of problem, please repackage it with jarjar to change the class packages

ffmpeg-jni.c:104: error: undefined reference to 'av_new_stream'

Hi,

I am getting ffmpeg-jni.c:104: error: undefined reference to 'av_new_stream' during C compilation (ndk-build) - when using latest versions of ffmpeg libraries & NDK r10c.

If a change the source code from -

audio_stream = av_new_stream(fmt_context, 1);

  • to -

audio_stream = avformat_new_stream(fmt_context, 1);

  • the code builds ok but then I get a run time seg fault during the avformat_new_stream call to create the audio stream -

11-12 22:29:17.253: I/ffmpeg-jni(7522): creating audio stream
11-12 22:29:17.253: A/libc(7522): Fatal signal 11 (SIGSEGV) at 0x00000009 (code=1), thread 7522 (id.apps.watchme)

Please advise / update ffmpeg-jni.c.

Is there some specific version of FFMPEG libraries required for successful build of the Watchme app ???

(I've spent over a week getting this far & I'm not giving up now ... ;-)

Regards

I am getting java.lang.NoClassDefFoundError when run the code

EXCEPTION: main
java.lang.NoClassDefFoundError: com.google.android.apps.watchme.util.ImageCache$RetainFragment
at com.google.android.apps.watchme.util.ImageCache.findOrCreateRetainFragment(ImageCache.java:255)
at com.google.android.apps.watchme.util.ImageCache.findOrCreateCache(ImageCache.java:107)
at com.google.android.apps.watchme.util.ImageWorker.addImageCache(ImageWorker.java:179)
at com.google.android.apps.watchme.MainActivity.ensureFetcher(MainActivity.java:129)
at com.google.android.apps.watchme.MainActivity.onGetImageFetcher(MainActivity.java:286)
at com.google.android.apps.watchme.EventsListFragment.onAttach(EventsListFragment.java:174)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:844)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1035)
at android.app.FragmentManagerImpl.addFragment(FragmentManager.java:1137)
at android.app.Activity.onCreateView(Activity.java:4735)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:680)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:746)
at android.view.LayoutInflater.inflate(LayoutInflater.java:489)
at android.view.LayoutInflater.inflate(LayoutInflater.java:396)
at android.view.LayoutInflater.inflate(LayoutInflater.java:352)
at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:274)
at android.app.Activity.setContentView(Activity.java:1881)
at com.google.android.apps.watchme.MainActivity.onCreate(MainActivity.java:78)
at android.app.Activity.performCreate(Activity.java:5122)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1081)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2270)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2358)
at android.app.ActivityThread.access$600(ActivityThread.java:156)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1340)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:153)
at android.app.ActivityThread.main(ActivityThread.java:5297)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:833)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
at dalvik.system.NativeStart.main(Native Method)

Please help me

Authentication error

When i run this project then got error of authentication.

com.google.android.apps.watchme E/GooglePlayServicesUtil﹕ The Google Play services resources were not found. Check your project configuration to ensure that the resources are included.
11-05 15:23:37.214 4356-4402/com.google.android.apps.watchme E/WatchMe﹕ com.google.api.client.googleapis.extensions.android.gms.auth.UserRecoverableAuthIOException
at com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential$RequestHandler.intercept(GoogleAccountCredential.java:284)
at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:859)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:410)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:343)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:460)
at com.google.android.apps.watchme.util.YouTubeApi.getLiveEvents(YouTubeApi.java:155)
at com.google.android.apps.watchme.MainActivity$GetLiveEventsTask.doInBackground(MainActivity.java:332)
at com.google.android.apps.watchme.MainActivity$GetLiveEventsTask.doInBackground(MainActivity.java:315)
at android.os.AsyncTask$2.call(AsyncTask.java:287)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
at java.util.concurrent.FutureTask.run(FutureTask.java:137)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
at java.lang.Thread.run(Thread.java:856)
Caused by: com.google.android.gms.auth.UserRecoverableAuthException: NeedPermission
at com.google.android.gms.auth.GoogleAuthUtil.getToken(Unknown Source)
at com.google.android.gms.auth.GoogleAuthUtil.getToken(Unknown Source)
at com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential.getToken(GoogleAccountCredential.java:255)
at com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential$RequestHandler.intercept(GoogleAccountCredential.java:279)
            at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:859)
            at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:410)
            at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:343)
            at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:460)
            at com.google.android.apps.watchme.util.YouTubeApi.getLiveEvents(YouTubeApi.java:155)
            at com.google.android.apps.watchme.MainActivity$GetLiveEventsTask.doInBackground(MainActivity.java:332)
            at com.google.android.apps.watchme.MainActivity$GetLiveEventsTask.doInBackground(MainActivity.java:315)
            at android.os.AsyncTask$2.call(AsyncTask.java:287)
            at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
            at java.util.concurrent.FutureTask.run(FutureTask.java:137)
            at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
            at java.lang.Thread.run(Thread.java:856)

Inclusion of FFmpeg Libraries

Hi, I compiled ffmpeg on linux and tried to include it into the project but it started throwing errors on the ffmpeg-jni.c file.

Here is the output:
/home/alex/Cs/youtube-yt-watchme-bca6784/app/src/main/jni/ffmpeg-jni.c
Error:(62, 3) error: 'for' loop initial declarations are only allowed in C99 or C11 mode
Error:(84, 3) error: format not a string literal and no format arguments [-Werror=format-security]
Warning:(103, 16) warning: assignment makes pointer from integer without a cast
Warning:(107, 18) warning: assignment makes pointer from integer without a cast
Error:(278, 3) error: 'for' loop initial declarations are only allowed in C99 or C11 mode
Warning:(298, 3) warning: 'avcodec_encode_video' is deprecated (declared at /home/alex/Cs/youtube-yt-watchme-bca6784/app/src/main/jni/libavcodec/avcodec.h:4476) [-Wdeprecated-declarations]
Warning:(345, 5) warning: 'avcodec_encode_audio' is deprecated (declared at /home/alex/Cs/youtube-yt-watchme-bca6784/app/src/main/jni/libavcodec/avcodec.h:4413) [-Wdeprecated-declarations]
int compressed_length = avcodec_encode_audio(audio_codec_ctx, out, 128000, AudioBuffer_Get());

2 problem about using watchme

First of all, I am already post the live stream on youtube successfully. Below is 2 problems I have met.

  • The frame per second is too low, I found it from my debug log. I found that the the fps is less than 3, it makes my streaming not smooth and youtube warned me to increase the bit rate.
  • The stream video do not have any sound, I have thought that is because of the fps too low but seems not really it is from watching the issues that other user recommended.

Sorry for my bad English, but I need a little help. Lets us discuss here?

Caused by: java.lang.NoSuchMethodError

I got this error ,when click on create event
Caused by: java.lang.NoSuchMethodError: com.google.api.client.googleapis.services.json.AbstractGoogleJsonClient.
Can i have list of supported jar for youtube live streaming so i can fix this issue?
Update here so i can fix this issue as soon as possible.

libavutil/common.h:83:23: fatal error: config.h: No such file or directory

Hi,

When I do a "ndk-build" to the android.mk provided, I have the error libavutil/common.h:83:23: fatal error: config.h: No such file or directory

Actually in this file common.h, I have
ifdef HAVE_AV_CONFIG_H
include "config.h"
include "intmath.h"
endif

But no config.h in the "android" folder that was generated with http://www.roman10.net/how-to-build-ffmpeg-with-ndk-r9/.
Do I have to use the config.h that is in the root of the ffmpeg folder?

I was trying to copy/paste all the missing headers, but there are a lot (it is a pain! :-)). Is this really what we have to do? (Copy paste the missing headers?) Why were not they directly under the "Android" folder $NDK/sources/ffmpeg-2.0.1/android, which contains arm/include folders.

Thank you!

Does there exist timeout API on YouTube API?

Dir sir,

When I try to connect with weak network environment, it always needs few minutes to let me know the YouTube live broadcast is created failed.

So I'm wondering that does there exist some timeout API to control this situation? Thanks a lot!

WatchMe project : Throwing runtime exception for different JARs

I have downloaded WatchMe project & imported in eclipse. Also, I tried to resolve compile time errors by importing all necessary jars.
But, when I run the project, I get different runtime errors such as

1] NoClassDefFoundError for HttpTransport transport = AndroidHttp.new Compatible Transport()

2] NoClassDefFoundError GoogleAccountCredential

3] NoClassDefFoundError GsonFactory

I tried a lot also googled almost all answers. But was unable to get with correct answer. Could somebody please help me out to resolve this issues?

The App is not Working

Whenever i was trying to start a app from my gmail account.The app shows a message "Loading events please wait" but after that nothing was happened.

java.lang.UnsatisfiedLinkError .android.apps.watchme.Ffmpeg.init

Hi , i am using this api for live streaming , but i am getting the below error when i try to create the Live stream

java.lang.UnsatisfiedLinkError: No implementation found for boolean com.google.android.apps.watchme.Ffmpeg.init(int, int, int, java.lang.String) (tried Java_com_google_android_apps_watchme_Ffmpeg_init and Java_com_google_android_apps_watchme_Ffmpeg_init__IIILjava_lang_String_2)
at com.google.android.apps.watchme.Ffmpeg.init(Native Method)
at com.google.android.apps.watchme.VideoStreamingConnection.open(VideoStreamingConnection.java:71)
at com.google.android.apps.watchme.StreamerService.startStreaming(StreamerService.java:72)
at com.google.android.apps.watchme.StreamerActivity.startStreaming(StreamerActivity.java:210)
at com.google.android.apps.watchme.StreamerActivity.access$200(StreamerActivity.java:47)
at com.google.android.apps.watchme.StreamerActivity$1.onServiceConnected(StreamerActivity.java:67)
at android.app.LoadedApk$ServiceDispatcher.doConnected(LoadedApk.java:1208)
at android.app.LoadedApk$ServiceDispatcher$RunConnection.run(LoadedApk.java:1225)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5343)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:905)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:700)

screencapture_2016-03-07_11 26 03

and Cannot resolve corresponding JNI function Java_com_google_android_apps_watchme_Ffmpeg_init less.
Reports native method declarations in Java where no corresponding JNI function is found in the project.

screencapture_2016-03-07_12 14 06

Building libFfmpeg.so

Hi there! Looks like a solid demo project, but I'm a little unclear as to how I can build a working libFfmpeg.so, and was wondering where to either find the file or instructions on how to build it myself.

  • Nick

YouTubeApi.java - the name must not be empty: null

Hello ,
YouTubeApi.java is throwing error (the name must not be empty: null) when I am trying to execute
LiveBroadcast returnedBroadcast = liveBroadcastInsert.execute();

Please suggest how to resolve the issue.

Here is the error that I am getting..

W/System.err﹕ Throwable1: [Ljava.lang.StackTraceElement;@42715a68
W/System.err﹕ java.lang.IllegalArgumentException: the name must not be empty: null
W/System.err﹕ at android.accounts.Account.(Account.java:48)
W/System.err﹕ at com.google.android.gms.auth.GoogleAuthUtil.getToken(Unknown Source)
W/System.err﹕ at com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential.getToken(GoogleAccountCredential.java:255)
W/System.err﹕ at com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential$RequestHandler.intercept(GoogleAccountCredential.java:279)
W/System.err﹕ at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:859)
W/System.err﹕ at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:419)
W/System.err﹕ at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:352)
W/System.err﹕ at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:469)
W/System.err﹕ at com.happytv.util.YouTubeApi.createLiveEvent(YouTubeApi.java:96)
W/System.err﹕ at MainActivity$CreateLiveEventTask.doInBackground(MainActivity.java:105)
W/System.err﹕ at MainActivity$CreateLiveEventTask.doInBackground(MainActivity.java:85)
W/System.err﹕ at android.os.AsyncTask$2.call(AsyncTask.java:287)
W/System.err﹕ at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
W/System.err﹕ at java.util.concurrent.FutureTask.run(FutureTask.java:137)
W/System.err﹕ at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
W/System.err﹕ at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
W/System.err﹕ at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
W/System.err﹕ at java.lang.Thread.run(Thread.java:856)

Thanks

Request Not Authorized in You Tube API in Live streaming

I create the live event but i can't seen events in my you tube account. I am very frustrated you tube watch me project. I can't implement its own in my android application. I can't create live event but I got Request not authorized". I can't use your jni code with ffmpeg. Please help for this problem. How to fix this problem.

Problem when using MediaCodec to encode audio & video instead of ffmpeg

Hey,

I managed to get the example working with audio and video but the video encoding is too slow so I'm now trying to use MediaCodec to encode video & audio and only use ffmpeg for the rtmp stream handling.

So far YouTube is accepting the video and audio stream (Stream is good) but all I get when watching the live stream on YouTube is a grey screen and sometimes I can see some encoding artifacts but that's it.

My guess is that the encoder configuration is somehow wrong or I need to configure the stream parameter differently, I'm using baseline profile, 30fps, 340p, 500kbit bitrate and audio is 44.1khz stereo.

Is there a reason why the example is not using MediaCodec?

YouTube should be able to decode a raw h264 stream from Android devices encoded with MediaCodec, or not?

Is someone able to live stream successfully a stream encoded with MediaCodec to YouTube?

Thanks,
Ralf

WatchMe - Android studio build issue

Hi, i have build this project with eclipse and it is running fine , but when i try to build this project in android studio i am error in my Ffmpeg class , please see the below
untitled

i have copy all the file from my running demo which i made in eclipse to my android studio project directory , i will post my directory structure and build.gradle , please anyone guide me?

untitled2

apply plugin: 'com.android.application'

android {
    compileSdkVersion 22
    buildToolsVersion "23.0.2"

    defaultConfig {
        applicationId "competent.groove.thegrooveboss"
        minSdkVersion 14
        targetSdkVersion 22
        versionCode 19
        versionName "1.1"
        // Enabling multidex support.
        multiDexEnabled true
    }
    sourceSets.main {
        jniLibs.srcDir 'src/main/jniLibs/armeabi'//set libs as .so's location instead of jni// src/main/jni/libs
        jni.srcDirs = [] //disable automatic ndk-build call
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    dexOptions {
        javaMaxHeapSize "4g"
    }
    compileOptions.encoding = 'ISO-8859-1'
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile project(':dialog')
    compile project(':observable_RecycleView_Demo')
    compile project(':zBarScannerActivity')
    compile project(':graphmain')
    compile files('libs/achartengine-1.1.0.jar')
    compile files('libs/FlurryAnalytics-4.0.0.jar')
    compile files('libs/gson-2.2.4.jar')
    compile files('libs/picasso-2.5.2.jar')
    compile files('libs/retrofit-1.9.0.jar')
    compile 'com.android.support:appcompat-v7:22.2.1'
    compile 'com.appyvet:materialrangebar:1.0'
    compile 'com.github.traex.rippleeffect:library:1.3'
    compile 'com.android.support:support-v4:23.0.1'
    compile 'com.google.android.gms:play-services-maps:8.1.0'
    compile 'com.google.android.gms:play-services-analytics:8.1.0'
    compile files('libs/aws-android-sdk-core-2.2.9.jar')
    compile files('libs/aws-android-sdk-s3-2.2.9.jar')
    compile project(':library')
    compile 'com.android.support:design:22.2.0'
    compile files('libs/hellocharts-library-1.5.8.jar')
    compile 'com.google.android.gms:play-services-gcm:8.1.0'
    compile files('libs/YouTubeAndroidPlayerApi.jar')
    compile files('libs/opencsv-3.7.jar')
    compile files('libs/google-api-client-1.19.0.jar')
    compile files('libs/google-api-client-android-1.19.0.jar')
    compile files('libs/google-api-client-gson-1.19.0.jar')
    compile files('libs/google-api-client-jackson2-1.19.0.jar')
    compile files('libs/google-api-services-youtube-v3-rev120-1.19.0.jar')
    compile files('libs/google-http-client-1.19.0.jar')
    compile files('libs/google-http-client-android-1.19.0.jar')
    compile files('libs/google-http-client-gson-1.19.0.jar')
    compile files('libs/google-http-client-jackson2-1.19.0.jar')
    compile files('libs/google-oauth-client-1.19.0.jar')
    compile files('libs/jackson-core-2.1.3.jar')
    compile files('libs/jsr305-1.3.9.jar')
    compile 'com.android.support:multidex:1.0.1'
    compile 'com.google.android.gms:play-services:8.1.0'
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.