当前位置: 首页 > 知识库问答 >
问题:

如何在KitKat 4.4中以编程方式录制Android屏幕视频

尹晟
2023-03-14

我知道这个问题已经被问了很多次,有很多问题、答案和讨论。但我不知道该做什么,不该做什么。

我已经参考了下面的链接,以获得解决方案,但运气不好。

https://stack overflow . com/questions/23438767/how-to-record-video-on-kit kat-4-4 < br > https://stack overflow . com/questions/23185125/I-cannot-Screen-record-with-my-kit kat-4-4-moto-x < br > Android kit kat start Screen record from App < br > Screen recorder with kit kat < br > Screen Recording kit kit kat with button kit

通过大量的搜索,我没有找到任何简单的例子来完成这项任务。两天以来,我一直在努力实现这一目标,但没有成功。

因此,简单的问题是是否有可能在Android中录制我们自己的屏幕的视频。我刚刚听说这是可能的从android 4.4基特,我也检查了一些从市场上的应用程序。

我知道要做到这一点,我们的设备应该扎根,以及这样做所需的其他事情。

但是我不知道如何通过编程来开发它。如果有人有任何想法,那么请指导我如何做到这一点。或者任何例子或者代码都会有很大的帮助。

感谢您的任何帮助。

我试图用这段简单的代码进行开发,但没有得到任何东西

public void startRecording(View v) {
        File recordfolder = Environment.getExternalStorageDirectory();
        String record = "su      — bit rate 8000000 --time-limit 30 "
                + recordfolder + "Record.mp4";
        recordfolder.mkdir();
        try {
            Process screenrecording = Runtime.getRuntime().exec(record);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

所以基本上我不知道我和这个过程屏幕录制有什么关系,我的意思是我该如何开始进步。

共有1个答案

全流觞
2023-03-14

好问题 但是答案取决于您要使用哪种类型的平台在Android中录制屏幕。

这里有一些技巧...

1)使用这个类,您可以记录您需要root设备的屏幕堡垒,您也可以在genymotion 4.4中进行测试。

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();
        }
    }
}

2) 您可以捕捉屏幕截图并从中制作视频,它将适用于3.0设备。对于将图像转换为视频,您可以使用FFMPEG或JavaCV。

-对于Rooted设备(因为您也可以捕获键盘屏幕)

if (Environment.MEDIA_MOUNTED.equals(Environment
            .getExternalStorageState())) {

        // we check if external storage is\ available, otherwise
        // display an error message to the user using Toast Message
        File sdCard = Environment.getExternalStorageDirectory();
        File directory = new File(sdCard.getAbsolutePath() + "/ScreenShots");
        directory.mkdirs();

        String filename = "screenshot_jpeg_" + i + ".png";
        File yourFile = new File(directory, filename);



        try {
            Process sh = Runtime.getRuntime().exec("su", null, null);
            OutputStream os = sh.getOutputStream();
            os.write(("/system/bin/screencap -p " + "/sdcard/ScreenShots/" + filename).getBytes("ASCII"));


            os.flush();
            os.close();
            sh.waitFor();
            i++;
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

- 对于没有root设备(因为您无法捕获键盘屏幕)

if (Environment.MEDIA_MOUNTED.equals(Environment
            .getExternalStorageState())) {

        // we check if external storage is\ available, otherwise
        // display an error message to the user using Toast Message
        File sdCard = Environment.getExternalStorageDirectory();
        File directory = new File(sdCard.getAbsolutePath() + "/ScreenShots");
        directory.mkdirs();

        String filename = "screenshot_jpeg_" + i + ".png";
        File yourFile = new File(directory, filename);



        try {
            Process sh = Runtime.getRuntime().exec("su", null, null);
            OutputStream os = sh.getOutputStream();
            os.write(("/system/bin/screencap -p " + "/sdcard/ScreenShots/" + filename).getBytes("ASCII"));


            os.flush();
            os.close();
            sh.waitFor();
            i++;
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
 类似资料:
  • Android将屏幕尺寸定义为普通的大屏幕等。 它会自动选择适当文件夹中的静态资源。我需要这个数据关于当前设备在我的java代码。DisplayMetrics仅提供有关当前设备密度的信息。没有关于屏幕大小可用。 我确实在grep代码中找到了屏幕大小枚举,但是这对我来说似乎不适用于4.0 SDK。有办法得到这些信息吗?

  • 在Android/Java中,是否有任何代码示例以编程方式捕获具有每秒良好帧的计算机的屏幕截图并创建视频? 我想要一个教程或完整的源代码来做到这一点。我希望该程序可以使用设备,而无需“植根”设备。 播放商店中有一个名为”的应用程序可以执行此操作。但是您需要ROOT设备才能使其正常工作,因此我知道这是可以做到的。 在无root设备上捕获Android屏幕截图并以编程方式创建视频的最佳方法是什么?

  • 我正在开发一个应用程序,我必须通过编程来锁定和解锁屏幕。好心帮忙!我不知道如何开发这种类型的功能,支持每个版本的Android操作系统。

  • 本文向大家介绍如何在iOS中以编程方式更改屏幕亮度?,包括了如何在iOS中以编程方式更改屏幕亮度?的使用技巧和注意事项,需要的朋友参考一下 要更改屏幕的亮度,我们必须使用屏幕的亮度属性。仅在主屏幕上支持此属性。此属性的值应为0.0到1.0之间的一个数字(含)。 应用程序所做的亮度更改将一直有效,直到锁定设备为止,无论应用程序是否关闭。下次打开显示器时,将恢复系统亮度(用户可以在“设置”或“控制中心

  • 我想创建一个应用程序,它可以将屏幕行为记录为视频,并以编程方式保存在设备上。有人能帮我吗?