首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在android中程序化录制超过3分钟的屏幕?

如何在android中程序化录制超过3分钟的屏幕?
EN

Stack Overflow用户
提问于 2014-06-08 14:29:46
回答 2查看 3.5K关注 0票数 4

我尝试在Android4.4上使用屏幕录制。我找到了一个代码示例,但是不能写超过3分钟的视频。我怎么才能绕过这个Android的限制呢?在一些应用程序中,比如Rec。此限制已被删除。

这就是我使用的例子。

代码语言:javascript
复制
public class MainActivity extends Activity {
private static final int RUNNING_NOTIFICATION_ID = 73;
private static final int FINISHED_NOTIFICATION_ID = 1337;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    if (savedInstanceState == null) {
        getFragmentManager().beginTransaction()
                .add(R.id.container, new MainFragment())
                .commit();
    }
}

public static class MainFragment extends Fragment {
    private Context mContext;

    private EditText mWidthEditText;
    private EditText mHeightEditText;
    private EditText mBitrateEditText;
    private EditText mTimeEditText;
    private Button mRecordButton;

    public MainFragment() {
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_main, container, false);

        mContext = getActivity();

        mRecordButton = (Button) rootView.findViewById(R.id.btn_record);
        mRecordButton.setOnClickListener(RecordOnClickListener);

        mWidthEditText = (EditText) rootView.findViewById(R.id.et_width);
        mHeightEditText = (EditText) rootView.findViewById(R.id.et_height);
        mBitrateEditText = (EditText) rootView.findViewById(R.id.et_bitrate);
        mBitrateEditText.addTextChangedListener(BitrateTextWatcher);
        mTimeEditText = (EditText) rootView.findViewById(R.id.et_time);
        mTimeEditText.addTextChangedListener(TimeTextWatcher);

        return rootView;
    }

    private TextWatcher BitrateTextWatcher = new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) {
            // Not used.
        }

        @Override
        public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) {
            if (TextUtils.isEmpty(charSequence)) {
                return;
            }

            int value = Integer.valueOf(charSequence.toString());
            if (value > 50 || value == 0) {
                mBitrateEditText.setError(mContext.getString(R.string.error_bitrate_edittext));
                return;
            }

            mTimeEditText.setError(null);
        }

        @Override
        public void afterTextChanged(Editable editable) {
            // Not used.
        }
    };

    private TextWatcher TimeTextWatcher = new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) {
            // Not used.
        }

        @Override
        public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) {
            if (TextUtils.isEmpty(charSequence)) {
                return;
            }

            int value = Integer.valueOf(charSequence.toString());
            if (value > 180 || value == 0) {
                mTimeEditText.setError(mContext.getString(R.string.error_time_editext));
                return;
            }

            mTimeEditText.setError(null);
        }

        @Override
        public void afterTextChanged(Editable editable) {
            // Not used.
        }
    };

    private View.OnClickListener RecordOnClickListener = new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            if (!TextUtils.isEmpty(mTimeEditText.getError()) || !TextUtils.isEmpty(mBitrateEditText.getError())) {
                Toast.makeText(mContext, mContext.getString(R.string.toast_invalid_values), Toast.LENGTH_LONG).show();
                return;
            }

            boolean widthSet = !TextUtils.isEmpty(mWidthEditText.getText());
            boolean heightSet = !TextUtils.isEmpty(mHeightEditText.getText());
            if ((!widthSet && heightSet) || (widthSet && !heightSet)) {
                Toast.makeText(mContext, mContext.getString(R.string.error_invalid_wxh), Toast.LENGTH_LONG).show();
                return;
            }

            boolean bitrateSet = !TextUtils.isEmpty(mBitrateEditText.getText());
            boolean timeSet = !TextUtils.isEmpty(mTimeEditText.getText());

            StringBuilder stringBuilder = new StringBuilder("/system/bin/screenrecord");
            if (widthSet) {
                stringBuilder.append(" --size ").append(mWidthEditText.getText()).append("x").append(mHeightEditText.getText());
            }
            if (bitrateSet) {
                stringBuilder.append(" --bit-rate ").append(mBitrateEditText.getText());
            }
            if (timeSet) {
                stringBuilder.append(" --time-limit ").append(mTimeEditText.getText());
            }

            // TODO User definable location.
            stringBuilder.append(" ").append(Environment.getExternalStorageDirectory().toString()).append("/recording.mp4");
            Log.d("TAG", "comamnd: " + stringBuilder.toString());

            try {
                new SuTask(stringBuilder.toString().getBytes("ASCII")).execute();

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

    private class SuTask extends AsyncTask<Boolean, Void, Boolean> {
        private final byte[] mCommand;

        public SuTask(byte[] command) {
            super();
            this.mCommand = command;
        }

        @Override
        protected Boolean doInBackground(Boolean... booleans) {
            try {
                Process sh = Runtime.getRuntime().exec("su", null, null);
                OutputStream outputStream = sh.getOutputStream();
                outputStream.write(mCommand);
                outputStream.flush();
                outputStream.close();

                final NotificationManager notificationManager = (NotificationManager) mContext.getSystemService(NOTIFICATION_SERVICE);
                notificationManager.notify(RUNNING_NOTIFICATION_ID, createRunningNotification(mContext));

                sh.waitFor();
                return true;

            } catch (InterruptedException e) {
                e.printStackTrace();
                Toast.makeText(mContext, mContext.getString(R.string.error_start_recording), Toast.LENGTH_LONG).show();

            } catch (IOException e) {
                e.printStackTrace();
                Toast.makeText(mContext, mContext.getString(R.string.error_start_recording), Toast.LENGTH_LONG).show();
            }

            return false;
        }

        @Override
        protected void onPostExecute(Boolean bool) {
            super.onPostExecute(bool);
            if (bool) {
                final NotificationManager notificationManager = (NotificationManager) mContext.getSystemService(NOTIFICATION_SERVICE);
                notificationManager.cancel(RUNNING_NOTIFICATION_ID);

                File file = new File(Environment.getExternalStorageDirectory().toString() + "/recording.mp4");
                notificationManager.notify(FINISHED_NOTIFICATION_ID, createFinishedNotification(mContext, file));
            }
        }

        private Notification createRunningNotification(Context context) {
            Notification.Builder mBuilder = new Notification.Builder(context)
                    .setSmallIcon(android.R.drawable.stat_notify_sdcard)
                    .setContentTitle(context.getResources().getString(R.string.app_name))
                    .setContentText("Recording Running")
                    .setTicker("Recording Running")
                    .setPriority(Integer.MAX_VALUE)
                    .setOngoing(true);

            return mBuilder.build();
        }

        private Notification createFinishedNotification(Context context, File file) {
            Intent intent = new Intent();
            intent.setAction(Intent.ACTION_VIEW);
            intent.setDataAndType(Uri.fromFile(file), "video/mp4");

            PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent,
                    PendingIntent.FLAG_UPDATE_CURRENT);

            Notification.Builder mBuilder = new Notification.Builder(context)
                    .setSmallIcon(android.R.drawable.stat_notify_sdcard)
                    .setContentTitle(context.getResources().getString(R.string.app_name))
                    .setContentText("Recording Finished")
                    .setTicker("Recording Finished")
                    .setContentIntent(pendingIntent)
                    .setOngoing(false)
                    .setAutoCancel(true);

            return mBuilder.build();
        }
    }
}

}
EN

回答 2

Stack Overflow用户

发布于 2014-06-08 15:12:18

你不能绕过3分钟的限制。您可以组合多个3分钟的视频来创建更长的视频。

如果您愿意编写自己的屏幕录制功能,那么您将需要在线程中连续截图,并将所有这些图像转换为视频。希望有一些库可以供您使用。

另一种选择是从你的应用程序中启动屏幕录制应用程序,但这将需要在设备上安装屏幕录制应用程序。

票数 3
EN

Stack Overflow用户

发布于 2018-12-12 05:02:03

您可以创建一个脚本来执行此操作。根据ADB documentation的说法,从命令行进行记录的方法是调用adb shell screenrecord [options] filename。将其放入脚本中,并使用循环计数器指定名称,您就可以获得一个很好的视频列表。使用adb pull /sdcard/*从SD卡中提取它们。

用于Windows的xda-developers示例脚本:

代码语言:javascript
复制
CALL :Record
SET /a var1=0
:record
SET /a var1+=1
SET /a name=%var1%
adb shell screenrecord /sdcard/recording%name%.mp4 --bit-rate 3145728
GOTO :record

将其另存为"record.bat“,就可以运行了:)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24103612

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档