Skip to content

Commit

Permalink
Merge pull request #41 from s0llvan/master
Browse files Browse the repository at this point in the history
Bad audio quality and missing notifications permission fixed, max camera frame rates refactoring
  • Loading branch information
anonfaded authored Sep 20, 2024
2 parents 2583788 + 9e18b31 commit d46e9fa
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 111 deletions.
1 change: 1 addition & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MICROPHONE" />


<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />



Expand Down
8 changes: 0 additions & 8 deletions app/src/main/java/com/fadcam/Constantes.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,6 @@ public abstract class Constantes {
public static final String PREF_VIDEO_FRAMERATE = "video_framerate";
public static final String PREF_CAMERA_SELECTION = "camera_selection";

public static int CAMERA_FRONT_FHD_MAX_FRAMERATES = 0;
public static int CAMERA_FRONT_HD_MAX_FRAMERATES = 0;
public static int CAMERA_FRONT_SD_MAX_FRAMERATES = 0;

public static int CAMERA_BACK_FHD_MAX_FRAMERATES = 0;
public static int CAMERA_BACK_HD_MAX_FRAMERATES = 0;
public static int CAMERA_BACK_SD_MAX_FRAMERATES = 0;

public static final String CAMERA_FRONT = "front";
public static final String CAMERA_BACK = "back";
}
38 changes: 36 additions & 2 deletions app/src/main/java/com/fadcam/ui/HomeFragment.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CameraManager;
import android.hardware.camera2.CaptureRequest;
import android.media.CamcorderProfile;
import android.media.MediaRecorder;
import android.os.Build;
import android.os.Bundle;
Expand Down Expand Up @@ -161,7 +162,8 @@ private void requestEssentialPermissions() {
Manifest.permission.CAMERA,
Manifest.permission.RECORD_AUDIO,
Manifest.permission.READ_MEDIA_VIDEO,
Manifest.permission.READ_EXTERNAL_STORAGE
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.POST_NOTIFICATIONS
};
} else { // Below Android 11
permissions = new String[]{
Expand Down Expand Up @@ -376,10 +378,11 @@ public void onResume() {
getActivity().registerReceiver(recordingStateReceiver, filter, Context.RECEIVER_NOT_EXPORTED);
}

setupStartStopButton();

updateStats();
}


@Override
public void onPause() {
super.onPause();
Expand Down Expand Up @@ -1005,6 +1008,10 @@ private String getCameraSelection() {
return sharedPreferences.getString(Constantes.PREF_CAMERA_SELECTION, Constantes.CAMERA_BACK);
}

private String getCameraQuality() {
return sharedPreferences.getString(Constantes.PREF_VIDEO_QUALITY, QUALITY_HD);
}

private void closeCamera() {
if (cameraDevice != null) {
cameraDevice.close();
Expand Down Expand Up @@ -1155,6 +1162,8 @@ private void setupMediaRecorder() {
mediaRecorder.setVideoFrameRate(selectedFramerate);
mediaRecorder.setCaptureRate(selectedFramerate);

mediaRecorder.setAudioEncodingBitRate(384000);
mediaRecorder.setAudioSamplingRate(48000);
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);

Expand Down Expand Up @@ -1581,6 +1590,31 @@ private void copyFile(InputStream in, OutputStream out) throws IOException {
}
}

private void setupStartStopButton()
{
if (!CamcorderProfile.hasProfile(1, CamcorderProfile.QUALITY_1080P) && getCameraSelection().equals(Constantes.CAMERA_FRONT) && getCameraQuality().equals(QUALITY_FHD)) {
buttonStartStop.setEnabled(false);
}
else if (!CamcorderProfile.hasProfile(1, CamcorderProfile.QUALITY_720P) && getCameraSelection().equals(Constantes.CAMERA_FRONT) && getCameraQuality().equals(QUALITY_HD)) {
buttonStartStop.setEnabled(false);
}
else if (!CamcorderProfile.hasProfile(1, CamcorderProfile.QUALITY_VGA) && !CamcorderProfile.hasProfile(1, CamcorderProfile.QUALITY_480P) && getCameraSelection().equals(Constantes.CAMERA_FRONT) && getCameraQuality().equals(QUALITY_SD)) {
buttonStartStop.setEnabled(false);
}
else if (!CamcorderProfile.hasProfile(0, CamcorderProfile.QUALITY_1080P) && getCameraSelection().equals(Constantes.CAMERA_BACK) && getCameraQuality().equals(QUALITY_FHD)) {
buttonStartStop.setEnabled(false);
}
else if (!CamcorderProfile.hasProfile(0, CamcorderProfile.QUALITY_720P) && getCameraSelection().equals(Constantes.CAMERA_BACK) && getCameraQuality().equals(QUALITY_HD)) {
buttonStartStop.setEnabled(false);
}
else if (!CamcorderProfile.hasProfile(0, CamcorderProfile.QUALITY_VGA) && !CamcorderProfile.hasProfile(0, CamcorderProfile.QUALITY_480P) && getCameraSelection().equals(Constantes.CAMERA_BACK) && getCameraQuality().equals(QUALITY_SD)) {
buttonStartStop.setEnabled(false);
}
else {
buttonStartStop.setEnabled(true);
}
}


@Override
public void onDestroyView() {
Expand Down
140 changes: 39 additions & 101 deletions app/src/main/java/com/fadcam/ui/SettingsFragment.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraManager;
import android.hardware.camera2.params.StreamConfigurationMap;
import android.media.CamcorderProfile;
import android.media.MediaRecorder;
import android.net.Uri;
import android.os.Build;
Expand Down Expand Up @@ -105,13 +106,9 @@ public void onResume() {
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_settings, container, false);


// Initialize shared preferences
sharedPreferences = requireActivity().getPreferences(Context.MODE_PRIVATE);

// Initialize maximum framerates for each resolution
initializeMaxResolutionFramerates();

// Setup language selection spinner items with array resource
Spinner languageSpinner = view.findViewById(R.id.language_spinner);
ArrayAdapter<CharSequence> languageAdapter = ArrayAdapter.createFromResource(
Expand Down Expand Up @@ -362,7 +359,9 @@ private void setupFrameRateSpinner() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
List<Integer> videoFrameratesCompatibles = getCompatiblesVideoFrameRates(getSharedPreferencesCameraSelection());
sharedPreferences.edit().putInt(Constantes.PREF_VIDEO_FRAMERATE, videoFrameratesCompatibles.get(position)).apply();
if(!videoFrameratesCompatibles.isEmpty()) {
sharedPreferences.edit().putInt(Constantes.PREF_VIDEO_FRAMERATE, videoFrameratesCompatibles.get(position)).apply();
}
}

@Override
Expand All @@ -388,8 +387,12 @@ private void updateFrameRateSpinner()
// Set the selected item based on the saved preference
int selectedFramerate = sharedPreferences.getInt(Constantes.PREF_VIDEO_FRAMERATE, Constantes.DEFAULT_VIDEO_FRAMERATE);

frameRateSpinner.setSelection(videoFrameratesCompatibles.size() == 1 ? 0 : getVideoFrameRateIndex(selectedFramerate));
frameRateSpinner.setEnabled(videoFrameratesCompatibles.size() > 1);
if(!videoFrameratesCompatibles.isEmpty()) {
frameRateSpinner.setSelection(videoFrameratesCompatibles.size() == 1 ? 0 : getVideoFrameRateIndex(selectedFramerate));
frameRateSpinner.setEnabled(videoFrameratesCompatibles.size() > 1);
} else {
frameRateSpinner.setEnabled(false);
}
}

private void setupWatermarkSpinner(View view, Spinner watermarkSpinner) {
Expand Down Expand Up @@ -571,69 +574,6 @@ private int getVideoQualityIndex()
return selectedIndex;
}

/**
* Initialize maximum framerates for each resolution
*/
private void initializeMaxResolutionFramerates()
{
CameraManager manager = (CameraManager) getActivity().getSystemService(Context.CAMERA_SERVICE);

for(int i = 0; i < 2;i++) {

CameraCharacteristics characteristics = null;

try {
String cameraId = manager.getCameraIdList()[i];
characteristics = manager.getCameraCharacteristics(cameraId);
}
catch (CameraAccessException cameraAccessException)
{
cameraAccessException.printStackTrace();
}

if(characteristics != null) {
StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
Size[] sizes = new Size[]{};
if (map != null) {
sizes = map.getOutputSizes(MediaRecorder.class);
}

for (Size size : sizes) {
Range<Integer>[] fpsRanges = characteristics.get(CameraCharacteristics.CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES);
if (fpsRanges != null) {
String[] resolutions = {"1920x1080", "1280x720", "640x480"};

for (Range<Integer> range : fpsRanges) {
for (int index = 0; index < resolutions.length; index++) {
if (size.toString().equals(resolutions[index])) {
if (i == 0) {
// Back camera
if (index == 0) {
Constantes.CAMERA_BACK_FHD_MAX_FRAMERATES = Math.max(Constantes.CAMERA_BACK_FHD_MAX_FRAMERATES, range.getUpper());
} else if (index == 1) {
Constantes.CAMERA_BACK_HD_MAX_FRAMERATES = Math.max(Constantes.CAMERA_BACK_HD_MAX_FRAMERATES, range.getUpper());
} else {
Constantes.CAMERA_BACK_SD_MAX_FRAMERATES = Math.max(Constantes.CAMERA_BACK_SD_MAX_FRAMERATES, range.getUpper());
}
} else {
// Front camera
if (index == 0) {
Constantes.CAMERA_FRONT_FHD_MAX_FRAMERATES = Math.max(Constantes.CAMERA_FRONT_FHD_MAX_FRAMERATES, range.getUpper());
} else if (index == 1) {
Constantes.CAMERA_FRONT_HD_MAX_FRAMERATES = Math.max(Constantes.CAMERA_FRONT_HD_MAX_FRAMERATES, range.getUpper());
} else {
Constantes.CAMERA_FRONT_SD_MAX_FRAMERATES = Math.max(Constantes.CAMERA_FRONT_SD_MAX_FRAMERATES, range.getUpper());
}
}
}
}
}
}
}
}
}
}

/**
* Get all compatibles video framerates
* @param camera (front or back)
Expand All @@ -648,32 +588,36 @@ public List<Integer> getCompatiblesVideoFrameRates(String camera)
int[] videoFrameRates = getResources().getIntArray(R.array.video_framerate_array);
List<Integer> videoFrameRatesCompatibles = new ArrayList<>();

CamcorderProfile profile = null;

// Determine the frame rate limits based on the camera and quality
int maxFrameRate = Constantes.DEFAULT_VIDEO_FRAMERATE;
if (camera.equals(Constantes.CAMERA_FRONT)) {
switch (selectedQuality) {
case QUALITY_FHD:
maxFrameRate = Constantes.CAMERA_FRONT_FHD_MAX_FRAMERATES;
break;
case QUALITY_HD:
maxFrameRate = Constantes.CAMERA_FRONT_HD_MAX_FRAMERATES;
break;
case QUALITY_SD:
maxFrameRate = Constantes.CAMERA_FRONT_SD_MAX_FRAMERATES;
break;
}
} else {
switch (selectedQuality) {
case QUALITY_FHD:
maxFrameRate = Constantes.CAMERA_BACK_FHD_MAX_FRAMERATES;
break;
case QUALITY_HD:
maxFrameRate = Constantes.CAMERA_BACK_HD_MAX_FRAMERATES;
break;
case QUALITY_SD:
maxFrameRate = Constantes.CAMERA_BACK_SD_MAX_FRAMERATES;
break;
}
int maxFrameRate = 0;
int cameraId = camera.equals(Constantes.CAMERA_FRONT) ? 1 : 0;

switch (selectedQuality) {
case QUALITY_FHD:
if (CamcorderProfile.hasProfile(cameraId, CamcorderProfile.QUALITY_1080P)) {
profile = CamcorderProfile.get(cameraId, CamcorderProfile.QUALITY_1080P);
}
break;
case QUALITY_HD:
if (CamcorderProfile.hasProfile(cameraId, CamcorderProfile.QUALITY_720P)) {
profile = CamcorderProfile.get(cameraId, CamcorderProfile.QUALITY_720P);
}
break;
case QUALITY_SD:
if (CamcorderProfile.hasProfile(cameraId, CamcorderProfile.QUALITY_VGA)) {
profile = CamcorderProfile.get(cameraId, CamcorderProfile.QUALITY_VGA);
}
else if (CamcorderProfile.hasProfile(cameraId, CamcorderProfile.QUALITY_480P)) {
profile = CamcorderProfile.get(cameraId, CamcorderProfile.QUALITY_480P);
}
break;
}

if(profile != null)
{
maxFrameRate = profile.videoFrameRate;
}

// Add the compatible frame rates to the list
Expand All @@ -683,12 +627,6 @@ public List<Integer> getCompatiblesVideoFrameRates(String camera)
}
}

// If no compatibles video framerates found, add default framerate
if(videoFrameRatesCompatibles.isEmpty())
{
videoFrameRatesCompatibles.add(Constantes.DEFAULT_VIDEO_FRAMERATE);
}

return videoFrameRatesCompatibles;
}

Expand Down

0 comments on commit d46e9fa

Please sign in to comment.