问:
Video compression using Telegram API rotating the video issue
I am trying to compress the video.
The code works fine if the video is in landscape mode, but gets rotated to landscape if the video is in portrait mode.
My code:

```public File convertVideo(String path) {
    MediaMetadataRetriever retriever = new MediaMetadataRetriever();
    try {
        FileInputStream inputStream = new FileInputStream(path);

        retriever.setDataSource(path);

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

    String width = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT);
    String height = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH);
    String rotation = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_ROTATION);

    long startTime = -1;
    long endTime = -1;

    int resultWidth = 640;
    int resultHeight = 360;

    int maxPortWidth = 360;
    int maxPortHeight = 640;

    int maxLandWidth = 640;
    int maxLandHeight = 360;

    float imgRatio;
    float maxRatio;

    int rotationValue = Integer.valueOf(rotation);
    int originalWidth = Integer.valueOf(width);
    int originalHeight = Integer.valueOf(height);

    int bitrate = 921600;
    int rotateRender = 0;

    File folder = new File(Environment.getExternalStorageDirectory() +  File.separator
            + Config.VIDEO_COMPRESSOR_APPLICATION_DIR_NAME);
    boolean isDirExist = false;
    if (!folder.exists()) {
        isDirExist = folder.mkdir();
    }
    isDirExist = false;
    folder = new File(Environment.getExternalStorageDirectory() +  File.separator
            + Config.VIDEO_COMPRESSOR_APPLICATION_DIR_NAME+ Config.VIDEO_COMPRESSOR_COMPRESSED_VIDEOS_DIR);
    if (!folder.exists()) {
        isDirExist = folder.mkdir();
    }

    File cacheFile = new File(
            Environment.getExternalStorageDirectory()
                    + File.separator
                    + Config.VIDEO_COMPRESSOR_APPLICATION_DIR_NAME
                    + Config.VIDEO_COMPRESSOR_COMPRESSED_VIDEOS_DIR,
            "VIDEO_" + new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()) + ".mp4"
    );

    if(rotation.equals("90") || rotation.equals("270")) {

        imgRatio = originalWidth / originalHeight;
        maxRatio = maxPortWidth / maxPortHeight;
        if (originalHeight > maxPortHeight || originalWidth > maxPortWidth) {
            if (imgRatio < maxRatio) {
                imgRatio = maxPortHeight / originalHeight;
                resultWidth = (int) (imgRatio * originalWidth);
                resultHeight = (int) maxPortHeight;
            } else if (imgRatio > maxRatio) {
                imgRatio = maxPortWidth / originalWidth;
                resultHeight = (int) (imgRatio * originalHeight);
                resultWidth = (int) maxPortWidth;
            } else {
                resultHeight = (int) maxPortHeight;
                resultWidth = (int) maxPortWidth;

            }
        }

    } else {

        imgRatio = originalWidth / originalHeight;
        maxRatio = maxLandWidth / maxLandHeight;
        if (originalHeight > maxLandHeight || originalWidth > maxLandWidth) {
            if (imgRatio!=0.0 && (imgRatio < maxRatio)) {
                imgRatio = maxLandHeight / originalHeight;
                resultWidth = (int) (imgRatio * originalWidth);
                resultHeight = (int) maxLandHeight;
            } else if (imgRatio!=0.0 && (imgRatio > maxRatio)) {
                imgRatio = maxLandWidth / originalWidth;
                resultHeight = (int) (imgRatio * originalHeight);
                resultWidth = (int) maxLandWidth;
            } else {
                resultHeight = (int) maxLandHeight;
                resultWidth = (int) maxLandWidth;

            }
        }
    }
    if (Build.VERSION.SDK_INT < 18 && resultHeight > resultWidth && resultWidth != originalWidth && resultHeight != originalHeight) {
        int temp = resultHeight;
        resultHeight = resultWidth;
        resultWidth = temp;
        rotationValue = 90;
        rotateRender = 270;
    } else if (Build.VERSION.SDK_INT > 20) {
        if(rotationValue == 0) {

            rotateRender = 0;
        } else if (rotationValue == 90) {
            int temp = resultHeight;
            resultHeight = resultWidth;
            resultWidth = temp;
            rotationValue = 0;
            rotateRender = 270;
        } else if (rotationValue == 180) {
            rotateRender = 180;
            rotationValue = 0;
        } else if (rotationValue == 270) {
            int temp = resultHeight;
            resultHeight = resultWidth;
            resultWidth = temp;
            rotationValue = 0;
            rotateRender = 90;
        }
    }
    File inputFile = new File(path);
    if (!inputFile.canRead()) {
        didWriteData(true, true);
        return null;
    } else {
    }

    videoConvertFirstWrite = true;
    boolean error = false;
    long videoStartTime = startTime;
    long time = System.currentTimeMillis();
    if (resultWidth != 0 && resultHeight != 0) {
        MP4Builder mediaMuxer = null;
        MediaExtractor extractor = null;

        try {
            MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
            Mp4Movie movie = new Mp4Movie();
            movie.setCacheFile(cacheFile);
            movie.setRotation(rotationValue);
            movie.setSize(resultWidth, resultHeight);
            mediaMuxer = new MP4Builder().createMovie(movie);
            extractor = new MediaExtractor();
            extractor.setDataSource(inputFile.toString());

            if (resultWidth != originalWidth || resultHeight != originalHeight) {
                int videoIndex;
                videoIndex = selectTrack(extractor, false);

                if (videoIndex >= 0) {
                    MediaCodec decoder = null;
                    MediaCodec encoder = null;
                    InputSurface inputSurface = null;
                    OutputSurface outputSurface = null;
                    try {
                        long videoTime = -1;
                        boolean outputDone = false;
                        boolean inputDone = false;
                        boolean decoderDone = false;
                        int swapUV = 0;
                        int videoTrackIndex = -5;

                        int colorFormat;
                        int processorType = PROCESSOR_TYPE_OTHER;
                        String manufacturer = Build.MANUFACTURER.toLowerCase();
                        if (Build.VERSION.SDK_INT < 18) {
                            MediaCodecInfo codecInfo = selectCodec(MIME_TYPE);
                            colorFormat = selectColorFormat(codecInfo, MIME_TYPE);
                            if (colorFormat == 0) {
                                throw new RuntimeException("no supported color format");
                            }
                            String codecName = codecInfo.getName();
                            if (codecName.contains("OMX.qcom.")) {
                                processorType = PROCESSOR_TYPE_QCOM;
                                if (Build.VERSION.SDK_INT == 16) {
                                    if (manufacturer.equals("lge") || manufacturer.equals("nokia")) {
                                        swapUV = 1;
                                    }
                                }
                            } else if (codecName.contains("OMX.Intel.")) {
                                processorType = PROCESSOR_TYPE_INTEL;
                            } else if (codecName.equals("OMX.MTK.VIDEO.ENCODER.AVC")) {
                                processorType = PROCESSOR_TYPE_MTK;
                            } else if (codecName.equals("OMX.SEC.AVC.Encoder")) {
                                processorType = PROCESSOR_TYPE_SEC;
                                swapUV = 1;
                            } else if (codecName.equals("OMX.TI.DUCATI1.VIDEO.H264E")) {
                                processorType = PROCESSOR_TYPE_TI;
                            }
                            Log.e("tmessages", "codec = " + codecInfo.getName() + " manufacturer = " + manufacturer + "device = " + Build.MODEL);
                        } else {
                            colorFormat = MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface;
                        }

                        int resultHeightAligned = resultHeight;
                        int padding = 0;
                        int bufferSize = resultWidth * resultHeight * 3 / 2;
                        if (processorType == PROCESSOR_TYPE_OTHER) {
                            if (resultHeight % 16 != 0) {
                                resultHeightAligned += (16 - (resultHeight % 16));
                                padding = resultWidth * (resultHeightAligned - resultHeight);
                                bufferSize += padding * 5 / 4;
                            }
                        } else if (processorType == PROCESSOR_TYPE_QCOM) {
                            if (!manufacturer.toLowerCase().equals("lge")) {
                                int uvoffset = (resultWidth * resultHeight + 2047) & ~2047;
                                padding = uvoffset - (resultWidth * resultHeight);
                                bufferSize += padding;
                            }
                        } else if (processorType == PROCESSOR_TYPE_TI) {

                        } else if (processorType == PROCESSOR_TYPE_MTK) {
                            if (manufacturer.equals("baidu")) {
                                resultHeightAligned += (16 - (resultHeight % 16));
                                padding = resultWidth * (resultHeightAligned - resultHeight);
                                bufferSize += padding * 5 / 4;
                            }
                        }

                        extractor.selectTrack(videoIndex);
                        if (startTime > 0) {
                            extractor.seekTo(startTime, MediaExtractor.SEEK_TO_PREVIOUS_SYNC);
                        } else {
                            extractor.seekTo(0, MediaExtractor.SEEK_TO_PREVIOUS_SYNC);
                        }
                        MediaFormat inputFormat = extractor.getTrackFormat(videoIndex);

                        MediaFormat outputFormat = MediaFormat.createVideoFormat(MIME_TYPE, resultWidth, resultHeight);
                        outputFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, colorFormat);
                        outputFormat.setInteger(MediaFormat.KEY_BIT_RATE, bitrate != 0 ? bitrate : 921600);
                        outputFormat.setInteger(MediaFormat.KEY_FRAME_RATE, 25);
                        outputFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 10);
                        if (Build.VERSION.SDK_INT < 18) {
                            outputFormat.setInteger("stride", resultWidth + 32);
                            outputFormat.setInteger("slice-height", resultHeight);
                        }

                        encoder = MediaCodec.createEncoderByType(MIME_TYPE);
                        encoder.configure(outputFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
                        if (Build.VERSION.SDK_INT >= 18) {
                            inputSurface = new InputSurface(encoder.createInputSurface());
                            inputSurface.makeCurrent();
                        }
                        encoder.start();

                        decoder = MediaCodec.createDecoderByType(inputFormat.getString(MediaFormat.KEY_MIME));
                        if (Build.VERSION.SDK_INT >= 18) {
                            outputSurface = new OutputSurface();
                        } else {
                            outputSurface = new OutputSurface(resultWidth, resultHeight, rotateRender);
                        }
                        decoder.configure(inputFormat, outputSurface.getSurface(), null, 0);
                        decoder.start();

                        final int TIMEOUT_USEC = 2500;
                        ByteBuffer[] decoderInputBuffers = null;
                        ByteBuffer[] encoderOutputBuffers = null;
                        ByteBuffer[] encoderInputBuffers = null;
                        if (Build.VERSION.SDK_INT < 21) {
                            decoderInputBuffers = decoder.getInputBuffers();
                            encoderOutputBuffers = encoder.getOutputBuffers();
                            if (Build.VERSION.SDK_INT < 18) {
                                encoderInputBuffers = encoder.getInputBuffers();
                            }
                        }

                        while (!outputDone) {
                            if (!inputDone) {
                                boolean eof = false;
                                int index = extractor.getSampleTrackIndex();
                                if (index == videoIndex) {
                                    int inputBufIndex = decoder.dequeueInputBuffer(TIMEOUT_USEC);
                                    if (inputBufIndex >= 0) {
                                        ByteBuffer inputBuf;
                                        if (Build.VERSION.SDK_INT < 21) {
                                            inputBuf = decoderInputBuffers[inputBufIndex];
                                        } else {
                                            inputBuf = decoder.getInputBuffer(inputBufIndex);
                                        }
                                        int chunkSize = extractor.readSampleData(inputBuf, 0);
                                        if (chunkSize < 0) {
                                            decoder.queueInputBuffer(inputBufIndex, 0, 0, 0L, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
                                            inputDone = true;
                                        } else {
                                            decoder.queueInputBuffer(inputBufIndex, 0, chunkSize, extractor.getSampleTime(), 0);
                                            extractor.advance();
                                        }
                                    }
                                } else if (index == -1) {
                                    eof = true;
                                }
                                if (eof) {
                                    int inputBufIndex = decoder.dequeueInputBuffer(TIMEOUT_USEC);
                                    if (inputBufIndex >= 0) {
                                        decoder.queueInputBuffer(inputBufIndex, 0, 0, 0L, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
                                        inputDone = true;
                                    }
                                }
                            }

                            boolean decoderOutputAvailable = !decoderDone;
                            boolean encoderOutputAvailable = true;
                            while (decoderOutputAvailable || encoderOutputAvailable) {
                                int encoderStatus = encoder.dequeueOutputBuffer(info, TIMEOUT_USEC);
                                if (encoderStatus == MediaCodec.INFO_TRY_AGAIN_LATER) {
                                    encoderOutputAvailable = false;
                                } else if (encoderStatus == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
                                    if (Build.VERSION.SDK_INT < 21) {
                                        encoderOutputBuffers = encoder.getOutputBuffers();
                                    }
                                } else if (encoderStatus == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
                                    MediaFormat newFormat = encoder.getOutputFormat();
                                    if (videoTrackIndex == -5) {
                                        videoTrackIndex = mediaMuxer.addTrack(newFormat, false);
                                    }
                                } else if (encoderStatus < 0) {
                                    throw new RuntimeException("unexpected result from encoder.dequeueOutputBuffer: " + encoderStatus);
                                } else {
                                    ByteBuffer encodedData;
                                    if (Build.VERSION.SDK_INT < 21) {
                                        encodedData = encoderOutputBuffers[encoderStatus];
                                    } else {
                                        encodedData = encoder.getOutputBuffer(encoderStatus);
                                    }
                                    if (encodedData == null) {
                                        throw new RuntimeException("encoderOutputBuffer " + encoderStatus + " was null");
                                    }
                                    if (info.size > 1) {
                                        if ((info.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) == 0) {
                                            if (mediaMuxer.writeSampleData(videoTrackIndex, encodedData, info, false)) {
                                                didWriteData(false, false);
                                            }
                                        } else if (videoTrackIndex == -5) {
                                            byte[] csd = new byte[info.size];
                                            encodedData.limit(info.offset + info.size);
                                            encodedData.position(info.offset);
                                            encodedData.get(csd);
                                            ByteBuffer sps = null;
                                            ByteBuffer pps = null;
                                            for (int a = info.size - 1; a >= 0; a--) {
                                                if (a > 3) {
                                                    if (csd[a] == 1 && csd[a - 1] == 0 && csd[a - 2] == 0 && csd[a - 3] == 0) {
                                                        sps = ByteBuffer.allocate(a - 3);
                                                        pps = ByteBuffer.allocate(info.size - (a - 3));
                                                        sps.put(csd, 0, a - 3).position(0);
                                                        pps.put(csd, a - 3, info.size - (a - 3)).position(0);
                                                        break;
                                                    }
                                                } else {
                                                    break;
                                                }
                                            }

                                            MediaFormat newFormat = MediaFormat.createVideoFormat(MIME_TYPE, resultWidth, resultHeight);
                                            if (sps != null && pps != null) {
                                                newFormat.setByteBuffer("csd-0", sps);
                                                newFormat.setByteBuffer("csd-1", pps);
                                            }
                                            videoTrackIndex = mediaMuxer.addTrack(newFormat, false);
                                        }
                                    }
                                    outputDone = (info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0;
                                    encoder.releaseOutputBuffer(encoderStatus, false);
                                }
                                if (encoderStatus != MediaCodec.INFO_TRY_AGAIN_LATER) {
                                    continue;
                                }

                                if (!decoderDone) {
                                    int decoderStatus = decoder.dequeueOutputBuffer(info, TIMEOUT_USEC);
                                    if (decoderStatus == MediaCodec.INFO_TRY_AGAIN_LATER) {
                                        decoderOutputAvailable = false;
                                    } else if (decoderStatus == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {

                                    } else if (decoderStatus == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
                                        MediaFormat newFormat = decoder.getOutputFormat();

                                    } else if (decoderStatus < 0) {
                                        throw new RuntimeException("unexpected result from decoder.dequeueOutputBuffer: " + decoderStatus);
                                    } else {
                                        boolean doRender;
                                        if (Build.VERSION.SDK_INT >= 18) {
                                            doRender = info.size != 0;
                                        } else {
                                            doRender = info.size != 0 || info.presentationTimeUs != 0;
                                        }
                                        if (endTime > 0 && info.presentationTimeUs >= endTime) {
                                            inputDone = true;
                                            decoderDone = true;
                                            doRender = false;
                                            info.flags |= MediaCodec.BUFFER_FLAG_END_OF_STREAM;
                                        }
                                        if (startTime > 0 && videoTime == -1) {
                                            if (info.presentationTimeUs < startTime) {
                                                doRender = false;

                                            } else {
                                                videoTime = info.presentationTimeUs;
                                            }
                                        }
                                        decoder.releaseOutputBuffer(decoderStatus, doRender);
                                        if (doRender) {
                                            boolean errorWait = false;
                                            try {
                                                outputSurface.awaitNewImage();
                                            } catch (Exception e) {
                                                errorWait = true;

                                            }
                                            if (!errorWait) {
                                                if (Build.VERSION.SDK_INT >= 18) {
                                                    outputSurface.drawImage(false);
                                                    inputSurface.setPresentationTime(info.presentationTimeUs * 1000);
                                                    inputSurface.swapBuffers();
                                                } else {
                                                    int inputBufIndex = encoder.dequeueInputBuffer(TIMEOUT_USEC);
                                                    if (inputBufIndex >= 0) {
                                                        outputSurface.drawImage(true);
                                                        ByteBuffer rgbBuf = outputSurface.getFrame();
                                                        ByteBuffer yuvBuf = encoderInputBuffers[inputBufIndex];
                                                        yuvBuf.clear();
                                                        convertVideoFrame(rgbBuf, yuvBuf, colorFormat, resultWidth, resultHeight, padding, swapUV);
                                                        encoder.queueInputBuffer(inputBufIndex, 0, bufferSize, info.presentationTimeUs, 0);
                                                    } else {

                                                    }
                                                }
                                            }
                                        }
                                        if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
                                            decoderOutputAvailable = false;

                                            if (Build.VERSION.SDK_INT >= 18) {
                                                encoder.signalEndOfInputStream();
                                            } else {
                                                int inputBufIndex = encoder.dequeueInputBuffer(TIMEOUT_USEC);
                                                if (inputBufIndex >= 0) {
                                                    encoder.queueInputBuffer(inputBufIndex, 0, 1, info.presentationTimeUs, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        if (videoTime != -1) {
                            videoStartTime = videoTime;
                        }
                    } catch (Exception e) {

                        error = true;
                    }

                    extractor.unselectTrack(videoIndex);

                    if (outputSurface != null) {
                        outputSurface.release();
                    }
                    if (inputSurface != null) {
                        inputSurface.release();
                    }
                    if (decoder != null) {
                        decoder.stop();
                        decoder.release();
                    }
                    if (encoder != null) {
                        encoder.stop();
                        encoder.release();
                    }
                }
            } else {
                long videoTime = readAndWriteTrack(extractor, mediaMuxer, info, startTime, endTime, cacheFile, false);

                if (videoTime != -1) {
                    videoStartTime = videoTime;
                }
            }
            if (!error) {
                readAndWriteTrack(extractor, mediaMuxer, info, videoStartTime, endTime, cacheFile, true);
            }
        } catch (Exception e) {
            error = true;

            e.printStackTrace();

        } finally {
            if (extractor != null) {
                extractor.release();
            }
            if (mediaMuxer != null) {
                try {
                    mediaMuxer.finishMovie(false);
                } catch (Exception e) {

                }
            }

        }
    } else {
        didWriteData(true, true);
        return null;
    }
    didWriteData(true, error);

    return cacheFile;
}
```

Telegram App video compression
https://github.com/lalongooo/VideoCompressor/blob/master/app/src/main/java/com/lalongooo/videocompressor/video/MediaController.java

答:
SOLVED

Simply put the condition before calling the compression function. Check the selected video height and width using MediaMetaDataRetriever and set if condition.For 1:1 ratio video also it converts to 640x360. So try to get Width and Height before compression and put logic for compress or not.

```<code>public void compress() {

Log.w("VideoMessage","eNTERED : "+inputPath);
lMediaMetadataRetriever.setDataSource(inputPath);
String lVideoWidth = lMediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH);
Log.w("VideoMessage","VideoWidth: "+lVideoWidth);
String lVideoHeight = lMediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT);
Log.w("VideoMessage","VideoHeight: "+lVideoHeight);
if(Integer.valueOf(lVideoWidth)<=640 || Integer.valueOf(lVideoHeight)<=360){
    Toast.makeText(this, "Video Already in compressed form", Toast.LENGTH_SHORT).show();
}
else{
    try2CreateCompressDir();
    outPath=Environment.getExternalStorageDirectory()
            + File.separator
            + APP_DIR
            + COMPRESSED_VIDEOS_DIR
            +"VIDEO_" + new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()) + ".mp4";

    new VideoCompressor.execute(inputPath,outPath);

}
</code>```

}

Body:
I am trying to compress the video.
The code works fine if the video is in landscape mode, but gets rotated to landscape if the video is in portrait mode.
My code:

public File convertVideo(String path) {
    MediaMetadataRetriever retriever = new MediaMetadataRetriever();
    try {
        FileInputStream inputStream = new FileInputStream(path);

        retriever.setDataSource(path);

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

    String width = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT);
    String height = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH);
    String rotation = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_ROTATION);

    long startTime = -1;
    long endTime = -1;

    int resultWidth = 640;
    int resultHeight = 360;

    int maxPortWidth = 360;
    int maxPortHeight = 640;

    int maxLandWidth = 640;
    int maxLandHeight = 360;

    float imgRatio;
    float maxRatio;

    int rotationValue = Integer.valueOf(rotation);
    int originalWidth = Integer.valueOf(width);
    int originalHeight = Integer.valueOf(height);

    int bitrate = 921600;
    int rotateRender = 0;

    File folder = new File(Environment.getExternalStorageDirectory() +  File.separator
            + Config.VIDEO_COMPRESSOR_APPLICATION_DIR_NAME);
    boolean isDirExist = false;
    if (!folder.exists()) {
        isDirExist = folder.mkdir();
    }
    isDirExist = false;
    folder = new File(Environment.getExternalStorageDirectory() +  File.separator
            + Config.VIDEO_COMPRESSOR_APPLICATION_DIR_NAME+ Config.VIDEO_COMPRESSOR_COMPRESSED_VIDEOS_DIR);
    if (!folder.exists()) {
        isDirExist = folder.mkdir();
    }

    File cacheFile = new File(
            Environment.getExternalStorageDirectory()
                    + File.separator
                    + Config.VIDEO_COMPRESSOR_APPLICATION_DIR_NAME
                    + Config.VIDEO_COMPRESSOR_COMPRESSED_VIDEOS_DIR,
            "VIDEO_" + new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()) + ".mp4"
    );

    if(rotation.equals("90") || rotation.equals("270")) {

        imgRatio = originalWidth / originalHeight;
        maxRatio = maxPortWidth / maxPortHeight;
        if (originalHeight > maxPortHeight || originalWidth > maxPortWidth) {
            if (imgRatio < maxRatio) {
                imgRatio = maxPortHeight / originalHeight;
                resultWidth = (int) (imgRatio * originalWidth);
                resultHeight = (int) maxPortHeight;
            } else if (imgRatio > maxRatio) {
                imgRatio = maxPortWidth / originalWidth;
                resultHeight = (int) (imgRatio * originalHeight);
                resultWidth = (int) maxPortWidth;
            } else {
                resultHeight = (int) maxPortHeight;
                resultWidth = (int) maxPortWidth;

            }
        }

    } else {

        imgRatio = originalWidth / originalHeight;
        maxRatio = maxLandWidth / maxLandHeight;
        if (originalHeight > maxLandHeight || originalWidth > maxLandWidth) {
            if (imgRatio!=0.0 && (imgRatio < maxRatio)) {
                imgRatio = maxLandHeight / originalHeight;
                resultWidth = (int) (imgRatio * originalWidth);
                resultHeight = (int) maxLandHeight;
            } else if (imgRatio!=0.0 && (imgRatio > maxRatio)) {
                imgRatio = maxLandWidth / originalWidth;
                resultHeight = (int) (imgRatio * originalHeight);
                resultWidth = (int) maxLandWidth;
            } else {
                resultHeight = (int) maxLandHeight;
                resultWidth = (int) maxLandWidth;

            }
        }
    }
    if (Build.VERSION.SDK_INT < 18 && resultHeight > resultWidth && resultWidth != originalWidth && resultHeight != originalHeight) {
        int temp = resultHeight;
        resultHeight = resultWidth;
        resultWidth = temp;
        rotationValue = 90;
        rotateRender = 270;
    } else if (Build.VERSION.SDK_INT > 20) {
        if(rotationValue == 0) {

            rotateRender = 0;
        } else if (rotationValue == 90) {
            int temp = resultHeight;
            resultHeight = resultWidth;
            resultWidth = temp;
            rotationValue = 0;
            rotateRender = 270;
        } else if (rotationValue == 180) {
            rotateRender = 180;
            rotationValue = 0;
        } else if (rotationValue == 270) {
            int temp = resultHeight;
            resultHeight = resultWidth;
            resultWidth = temp;
            rotationValue = 0;
            rotateRender = 90;
        }
    }
    File inputFile = new File(path);
    if (!inputFile.canRead()) {
        didWriteData(true, true);
        return null;
    } else {
    }

    videoConvertFirstWrite = true;
    boolean error = false;
    long videoStartTime = startTime;
    long time = System.currentTimeMillis();
    if (resultWidth != 0 && resultHeight != 0) {
        MP4Builder mediaMuxer = null;
        MediaExtractor extractor = null;

        try {
            MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
            Mp4Movie movie = new Mp4Movie();
            movie.setCacheFile(cacheFile);
            movie.setRotation(rotationValue);
            movie.setSize(resultWidth, resultHeight);
            mediaMuxer = new MP4Builder().createMovie(movie);
            extractor = new MediaExtractor();
            extractor.setDataSource(inputFile.toString());

            if (resultWidth != originalWidth || resultHeight != originalHeight) {
                int videoIndex;
                videoIndex = selectTrack(extractor, false);

                if (videoIndex >= 0) {
                    MediaCodec decoder = null;
                    MediaCodec encoder = null;
                    InputSurface inputSurface = null;
                    OutputSurface outputSurface = null;
                    try {
                        long videoTime = -1;
                        boolean outputDone = false;
                        boolean inputDone = false;
                        boolean decoderDone = false;
                        int swapUV = 0;
                        int videoTrackIndex = -5;

                        int colorFormat;
                        int processorType = PROCESSOR_TYPE_OTHER;
                        String manufacturer = Build.MANUFACTURER.toLowerCase();
                        if (Build.VERSION.SDK_INT < 18) {
                            MediaCodecInfo codecInfo = selectCodec(MIME_TYPE);
                            colorFormat = selectColorFormat(codecInfo, MIME_TYPE);
                            if (colorFormat == 0) {
                                throw new RuntimeException("no supported color format");
                            }
                            String codecName = codecInfo.getName();
                            if (codecName.contains("OMX.qcom.")) {
                                processorType = PROCESSOR_TYPE_QCOM;
                                if (Build.VERSION.SDK_INT == 16) {
                                    if (manufacturer.equals("lge") || manufacturer.equals("nokia")) {
                                        swapUV = 1;
                                    }
                                }
                            } else if (codecName.contains("OMX.Intel.")) {
                                processorType = PROCESSOR_TYPE_INTEL;
                            } else if (codecName.equals("OMX.MTK.VIDEO.ENCODER.AVC")) {
                                processorType = PROCESSOR_TYPE_MTK;
                            } else if (codecName.equals("OMX.SEC.AVC.Encoder")) {
                                processorType = PROCESSOR_TYPE_SEC;
                                swapUV = 1;
                            } else if (codecName.equals("OMX.TI.DUCATI1.VIDEO.H264E")) {
                                processorType = PROCESSOR_TYPE_TI;
                            }
                            Log.e("tmessages", "codec = " + codecInfo.getName() + " manufacturer = " + manufacturer + "device = " + Build.MODEL);
                        } else {
                            colorFormat = MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface;
                        }

                        int resultHeightAligned = resultHeight;
                        int padding = 0;
                        int bufferSize = resultWidth * resultHeight * 3 / 2;
                        if (processorType == PROCESSOR_TYPE_OTHER) {
                            if (resultHeight % 16 != 0) {
                                resultHeightAligned += (16 - (resultHeight % 16));
                                padding = resultWidth * (resultHeightAligned - resultHeight);
                                bufferSize += padding * 5 / 4;
                            }
                        } else if (processorType == PROCESSOR_TYPE_QCOM) {
                            if (!manufacturer.toLowerCase().equals("lge")) {
                                int uvoffset = (resultWidth * resultHeight + 2047) & ~2047;
                                padding = uvoffset - (resultWidth * resultHeight);
                                bufferSize += padding;
                            }
                        } else if (processorType == PROCESSOR_TYPE_TI) {

                        } else if (processorType == PROCESSOR_TYPE_MTK) {
                            if (manufacturer.equals("baidu")) {
                                resultHeightAligned += (16 - (resultHeight % 16));
                                padding = resultWidth * (resultHeightAligned - resultHeight);
                                bufferSize += padding * 5 / 4;
                            }
                        }

                        extractor.selectTrack(videoIndex);
                        if (startTime > 0) {
                            extractor.seekTo(startTime, MediaExtractor.SEEK_TO_PREVIOUS_SYNC);
                        } else {
                            extractor.seekTo(0, MediaExtractor.SEEK_TO_PREVIOUS_SYNC);
                        }
                        MediaFormat inputFormat = extractor.getTrackFormat(videoIndex);

                        MediaFormat outputFormat = MediaFormat.createVideoFormat(MIME_TYPE, resultWidth, resultHeight);
                        outputFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, colorFormat);
                        outputFormat.setInteger(MediaFormat.KEY_BIT_RATE, bitrate != 0 ? bitrate : 921600);
                        outputFormat.setInteger(MediaFormat.KEY_FRAME_RATE, 25);
                        outputFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 10);
                        if (Build.VERSION.SDK_INT < 18) {
                            outputFormat.setInteger("stride", resultWidth + 32);
                            outputFormat.setInteger("slice-height", resultHeight);
                        }

                        encoder = MediaCodec.createEncoderByType(MIME_TYPE);
                        encoder.configure(outputFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
                        if (Build.VERSION.SDK_INT >= 18) {
                            inputSurface = new InputSurface(encoder.createInputSurface());
                            inputSurface.makeCurrent();
                        }
                        encoder.start();

                        decoder = MediaCodec.createDecoderByType(inputFormat.getString(MediaFormat.KEY_MIME));
                        if (Build.VERSION.SDK_INT >= 18) {
                            outputSurface = new OutputSurface();
                        } else {
                            outputSurface = new OutputSurface(resultWidth, resultHeight, rotateRender);
                        }
                        decoder.configure(inputFormat, outputSurface.getSurface(), null, 0);
                        decoder.start();

                        final int TIMEOUT_USEC = 2500;
                        ByteBuffer[] decoderInputBuffers = null;
                        ByteBuffer[] encoderOutputBuffers = null;
                        ByteBuffer[] encoderInputBuffers = null;
                        if (Build.VERSION.SDK_INT < 21) {
                            decoderInputBuffers = decoder.getInputBuffers();
                            encoderOutputBuffers = encoder.getOutputBuffers();
                            if (Build.VERSION.SDK_INT < 18) {
                                encoderInputBuffers = encoder.getInputBuffers();
                            }
                        }

                        while (!outputDone) {
                            if (!inputDone) {
                                boolean eof = false;
                                int index = extractor.getSampleTrackIndex();
                                if (index == videoIndex) {
                                    int inputBufIndex = decoder.dequeueInputBuffer(TIMEOUT_USEC);
                                    if (inputBufIndex >= 0) {
                                        ByteBuffer inputBuf;
                                        if (Build.VERSION.SDK_INT < 21) {
                                            inputBuf = decoderInputBuffers[inputBufIndex];
                                        } else {
                                            inputBuf = decoder.getInputBuffer(inputBufIndex);
                                        }
                                        int chunkSize = extractor.readSampleData(inputBuf, 0);
                                        if (chunkSize < 0) {
                                            decoder.queueInputBuffer(inputBufIndex, 0, 0, 0L, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
                                            inputDone = true;
                                        } else {
                                            decoder.queueInputBuffer(inputBufIndex, 0, chunkSize, extractor.getSampleTime(), 0);
                                            extractor.advance();
                                        }
                                    }
                                } else if (index == -1) {
                                    eof = true;
                                }
                                if (eof) {
                                    int inputBufIndex = decoder.dequeueInputBuffer(TIMEOUT_USEC);
                                    if (inputBufIndex >= 0) {
                                        decoder.queueInputBuffer(inputBufIndex, 0, 0, 0L, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
                                        inputDone = true;
                                    }
                                }
                            }

                            boolean decoderOutputAvailable = !decoderDone;
                            boolean encoderOutputAvailable = true;
                            while (decoderOutputAvailable || encoderOutputAvailable) {
                                int encoderStatus = encoder.dequeueOutputBuffer(info, TIMEOUT_USEC);
                                if (encoderStatus == MediaCodec.INFO_TRY_AGAIN_LATER) {
                                    encoderOutputAvailable = false;
                                } else if (encoderStatus == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
                                    if (Build.VERSION.SDK_INT < 21) {
                                        encoderOutputBuffers = encoder.getOutputBuffers();
                                    }
                                } else if (encoderStatus == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
                                    MediaFormat newFormat = encoder.getOutputFormat();
                                    if (videoTrackIndex == -5) {
                                        videoTrackIndex = mediaMuxer.addTrack(newFormat, false);
                                    }
                                } else if (encoderStatus < 0) {
                                    throw new RuntimeException("unexpected result from encoder.dequeueOutputBuffer: " + encoderStatus);
                                } else {
                                    ByteBuffer encodedData;
                                    if (Build.VERSION.SDK_INT < 21) {
                                        encodedData = encoderOutputBuffers[encoderStatus];
                                    } else {
                                        encodedData = encoder.getOutputBuffer(encoderStatus);
                                    }
                                    if (encodedData == null) {
                                        throw new RuntimeException("encoderOutputBuffer " + encoderStatus + " was null");
                                    }
                                    if (info.size > 1) {
                                        if ((info.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) == 0) {
                                            if (mediaMuxer.writeSampleData(videoTrackIndex, encodedData, info, false)) {
                                                didWriteData(false, false);
                                            }
                                        } else if (videoTrackIndex == -5) {
                                            byte[] csd = new byte[info.size];
                                            encodedData.limit(info.offset + info.size);
                                            encodedData.position(info.offset);
                                            encodedData.get(csd);
                                            ByteBuffer sps = null;
                                            ByteBuffer pps = null;
                                            for (int a = info.size - 1; a >= 0; a--) {
                                                if (a > 3) {
                                                    if (csd[a] == 1 && csd[a - 1] == 0 && csd[a - 2] == 0 && csd[a - 3] == 0) {
                                                        sps = ByteBuffer.allocate(a - 3);
                                                        pps = ByteBuffer.allocate(info.size - (a - 3));
                                                        sps.put(csd, 0, a - 3).position(0);
                                                        pps.put(csd, a - 3, info.size - (a - 3)).position(0);
                                                        break;
                                                    }
                                                } else {
                                                    break;
                                                }
                                            }

                                            MediaFormat newFormat = MediaFormat.createVideoFormat(MIME_TYPE, resultWidth, resultHeight);
                                            if (sps != null && pps != null) {
                                                newFormat.setByteBuffer("csd-0", sps);
                                                newFormat.setByteBuffer("csd-1", pps);
                                            }
                                            videoTrackIndex = mediaMuxer.addTrack(newFormat, false);
                                        }
                                    }
                                    outputDone = (info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0;
                                    encoder.releaseOutputBuffer(encoderStatus, false);
                                }
                                if (encoderStatus != MediaCodec.INFO_TRY_AGAIN_LATER) {
                                    continue;
                                }

                                if (!decoderDone) {
                                    int decoderStatus = decoder.dequeueOutputBuffer(info, TIMEOUT_USEC);
                                    if (decoderStatus == MediaCodec.INFO_TRY_AGAIN_LATER) {
                                        decoderOutputAvailable = false;
                                    } else if (decoderStatus == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {

                                    } else if (decoderStatus == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
                                        MediaFormat newFormat = decoder.getOutputFormat();

                                    } else if (decoderStatus < 0) {
                                        throw new RuntimeException("unexpected result from decoder.dequeueOutputBuffer: " + decoderStatus);
                                    } else {
                                        boolean doRender;
                                        if (Build.VERSION.SDK_INT >= 18) {
                                            doRender = info.size != 0;
                                        } else {
                                            doRender = info.size != 0 || info.presentationTimeUs != 0;
                                        }
                                        if (endTime > 0 && info.presentationTimeUs >= endTime) {
                                            inputDone = true;
                                            decoderDone = true;
                                            doRender = false;
                                            info.flags |= MediaCodec.BUFFER_FLAG_END_OF_STREAM;
                                        }
                                        if (startTime > 0 && videoTime == -1) {
                                            if (info.presentationTimeUs < startTime) {
                                                doRender = false;

                                            } else {
                                                videoTime = info.presentationTimeUs;
                                            }
                                        }
                                        decoder.releaseOutputBuffer(decoderStatus, doRender);
                                        if (doRender) {
                                            boolean errorWait = false;
                                            try {
                                                outputSurface.awaitNewImage();
                                            } catch (Exception e) {
                                                errorWait = true;

                                            }
                                            if (!errorWait) {
                                                if (Build.VERSION.SDK_INT >= 18) {
                                                    outputSurface.drawImage(false);
                                                    inputSurface.setPresentationTime(info.presentationTimeUs * 1000);
                                                    inputSurface.swapBuffers();
                                                } else {
                                                    int inputBufIndex = encoder.dequeueInputBuffer(TIMEOUT_USEC);
                                                    if (inputBufIndex >= 0) {
                                                        outputSurface.drawImage(true);
                                                        ByteBuffer rgbBuf = outputSurface.getFrame();
                                                        ByteBuffer yuvBuf = encoderInputBuffers[inputBufIndex];
                                                        yuvBuf.clear();
                                                        convertVideoFrame(rgbBuf, yuvBuf, colorFormat, resultWidth, resultHeight, padding, swapUV);
                                                        encoder.queueInputBuffer(inputBufIndex, 0, bufferSize, info.presentationTimeUs, 0);
                                                    } else {

                                                    }
                                                }
                                            }
                                        }
                                        if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
                                            decoderOutputAvailable = false;

                                            if (Build.VERSION.SDK_INT >= 18) {
                                                encoder.signalEndOfInputStream();
                                            } else {
                                                int inputBufIndex = encoder.dequeueInputBuffer(TIMEOUT_USEC);
                                                if (inputBufIndex >= 0) {
                                                    encoder.queueInputBuffer(inputBufIndex, 0, 1, info.presentationTimeUs, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        if (videoTime != -1) {
                            videoStartTime = videoTime;
                        }
                    } catch (Exception e) {

                        error = true;
                    }

                    extractor.unselectTrack(videoIndex);

                    if (outputSurface != null) {
                        outputSurface.release();
                    }
                    if (inputSurface != null) {
                        inputSurface.release();
                    }
                    if (decoder != null) {
                        decoder.stop();
                        decoder.release();
                    }
                    if (encoder != null) {
                        encoder.stop();
                        encoder.release();
                    }
                }
            } else {
                long videoTime = readAndWriteTrack(extractor, mediaMuxer, info, startTime, endTime, cacheFile, false);

                if (videoTime != -1) {
                    videoStartTime = videoTime;
                }
            }
            if (!error) {
                readAndWriteTrack(extractor, mediaMuxer, info, videoStartTime, endTime, cacheFile, true);
            }
        } catch (Exception e) {
            error = true;

            e.printStackTrace();

        } finally {
            if (extractor != null) {
                extractor.release();
            }
            if (mediaMuxer != null) {
                try {
                    mediaMuxer.finishMovie(false);
                } catch (Exception e) {

                }
            }

        }
    } else {
        didWriteData(true, true);
        return null;
    }
    didWriteData(true, error);

    return cacheFile;
}

Telegram App video compression
https://github.com/lalongooo/VideoCompressor/blob/master/app/src/main/java/com/lalongooo/videocompressor/video/MediaController.java

Body:
SOLVED

Simply put the condition before calling the compression function. Check the selected video height and width using MediaMetaDataRetriever and set if condition.For 1:1 ratio video also it converts to 640x360. So try to get Width and Height before compression and put logic for compress or not.

public void compress() {

Log.w("VideoMessage","eNTERED : "+inputPath);
lMediaMetadataRetriever.setDataSource(inputPath);
String lVideoWidth = lMediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH);
Log.w("VideoMessage","VideoWidth: "+lVideoWidth);
String lVideoHeight = lMediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT);
Log.w("VideoMessage","VideoHeight: "+lVideoHeight);
if(Integer.valueOf(lVideoWidth)<=640 || Integer.valueOf(lVideoHeight)<=360){
    Toast.makeText(this, "Video Already in compressed form", Toast.LENGTH_SHORT).show();
}
else{
    try2CreateCompressDir();
    outPath=Environment.getExternalStorageDirectory()
            + File.separator
            + APP_DIR
            + COMPRESSED_VIDEOS_DIR
            +"VIDEO_" + new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()) + ".mp4";

    new VideoCompressor.execute(inputPath,outPath);

}

}


来源: stackexchange

问:
Unclear relationship between pointer dereferencing and casting in a specific scenario
I have the following Cpp funtion:

```<code>u_long stringIpV4ToBinary(const char * ipv4)
{
    u_long * buff[1];
    int ret = InetPton(AF_INET, ipv4, &buff);
    if (ret == -1) return 1;
    if (ret == 0) return 1; // more handling needs to be added

// return ntohl(*buff[0]);           // crash, no warning
// return ntohl((*buff)[0]);         // same meaning above (??) crash, no warning
// return ntohl(**buff);             // crash, no warning
// return ntohl(*(buff[0]));         // crash, no warning
// return ntohl(*(u_long*)buff[0]);  // crash, no warning
// return ntohl((u_long)buff[0]);    // works, but produces warnings:: 'type cast': truncation from 'u_long *' to 'u_long'
// return ntohl(*(u_long*)&buff);    // works
// return ntohl(*(u_long*)&buff[0]); // works
// return ntohl(*(u_long*)buff[0]);  // crash, no warning
// return ntohl(*(u_long*)buff);     // works
}
</code>```

I have spent some time trying to extract the value of buff that I need to pass to ntohl() (so you can ignore the first couple of lines). I was playing around with *buff[0] *buff and others, w/o realizing that I need to cast the value of the first element of the array (&buff[0], buff or &buff).

Question: why do I need to cast the retrieved value to (u_long*) and then deference the pointer? Is it ambiguous or unclear to @ runtime that the value held in the buff[0] will be a of type u_long * ?  My expectation was that ntohl(**buff) - (buff is the array name, that decays into a pointer and since the array is of u_long pointers itself) double dereferencing should suffice.

答:
The call to InetPton writes a 32 bit IPv4 address to the first u_long * in buff.

All your variants that double-dereference are treating that value as if it were a pointer. It isn't, which is why they crash.

The ones that work manage to do only a single dereference and have the result treated as a long, which is why they work. (Although I suspect many of them actually have unspecified or undefined behaviour since you are being pretty cavalier about whether the value is a pointer or integer.)

If you declared buff as an IN_ADDR your code could be both simpler and clearly correct.

ContentLicense: CC BY-SA 3.0

Body:
I have the following Cpp funtion:

u_long stringIpV4ToBinary(const char * ipv4)
{
    u_long * buff[1];
    int ret = InetPton(AF_INET, ipv4, &buff);
    if (ret == -1) return 1;
    if (ret == 0) return 1; // more handling needs to be added

// return ntohl(*buff[0]);           // crash, no warning
// return ntohl((*buff)[0]);         // same meaning above (??) crash, no warning
// return ntohl(**buff);             // crash, no warning
// return ntohl(*(buff[0]));         // crash, no warning
// return ntohl(*(u_long*)buff[0]);  // crash, no warning
// return ntohl((u_long)buff[0]);    // works, but produces warnings:: 'type cast': truncation from 'u_long *' to 'u_long'
// return ntohl(*(u_long*)&buff);    // works
// return ntohl(*(u_long*)&buff[0]); // works
// return ntohl(*(u_long*)buff[0]);  // crash, no warning
// return ntohl(*(u_long*)buff);     // works
}

I have spent some time trying to extract the value of buff that I need to pass to ntohl() (so you can ignore the first couple of lines). I was playing around with *buff[0] *buff and others, w/o realizing that I need to cast the value of the first element of the array (&buff[0], buff or &buff).

Question: why do I need to cast the retrieved value to (u_long*) and then deference the pointer? Is it ambiguous or unclear to @ runtime that the value held in the buff[0] will be a of type u_long * ?  My expectation was that ntohl(**buff) - (buff is the array name, that decays into a pointer and since the array is of u_long pointers itself) double dereferencing should suffice.


问:
Different List initializing in GWT?
While learning GWT I faced another type of initialization.
I'm wondering what is the difference between:

```<code> 1) List<T> = new ArrayList<T>();
</code>```

and

```<code> 2) List<T> = Lists.newArrayList();
</code>```

Which one has advantages and why?

答:
I can only suppose:

When you work with generics it's not convenient to set T both in List<T> and new ArrayList<T>();
To resolve this drawback static helper methods are used:

```<code>List<T> = Lists.newArrayList();
</code>```

Here type T is defined via type inference. A a rule such methods are implemented like this:

```<code>public static <T> List<T> newArrayList() {
    return new ArrayList<T>();
}
</code>```

ContentLicense: CC BY-SA 2.5

Title: Different List initializing in GWT?

Body:
While learning GWT I faced another type of initialization.
I'm wondering what is the difference between:

 1) List<T> = new ArrayList<T>();

and

 2) List<T> = Lists.newArrayList();

Which one has advantages and why?

Body:
I can only suppose:

When you work with generics it's not convenient to set T both in List<T> and new ArrayList<T>();
To resolve this drawback static helper methods are used:

List<T> = Lists.newArrayList();

Here type T is defined via type inference. A a rule such methods are implemented like this:

public static <T> List<T> newArrayList() {
    return new ArrayList<T>();
}


问:
SQL Server: Replace values in field using lookup other table
Let's say I have below table script

```<code>DECLARE @result TABLE
   (
    [ID] Int
   ,[Data] Varchar(500)
   )
DECLARE @codes TABLE
   (
    [ID] Varchar(500)
   ,[FullNames] Varchar(500)
   )
INSERT   INTO @result
         SELECT   1
                 ,'[A]-[B]'
INSERT   INTO @result
         SELECT   2
                 ,'[D]-[A]'
INSERT   INTO @result
         SELECT   3
                 ,'[A]+[C]'

INSERT   INTO @codes
         SELECT   'A'
                 ,'10'
INSERT   INTO @codes
         SELECT   'B'
                 ,'20'
INSERT   INTO @codes
         SELECT   'C'
                 ,'30'
INSERT   INTO @codes
         SELECT   'D'
                 ,'40'

SELECT * FROM @result
SELECT * FROM @codes
</code>```

Output of those are as below:
@result

```<code>ID  Data
--  -------
1   [A]-[B]
2   [D]-[A]
3   [A]+[C]
</code>```

@codes

```<code>ID  FullNames
--  -------
A   10
B   20
C   30
D   40
</code>```

Now I want output as below also:

```<code>ID  Data
--  -----
1   10-20
2   40-10
3   10+30
</code>```

Please help me.
Please note: Data columns also contains ([A]-[B]+[D])*[C]

I found similar solution on https://stackoverflow.com/a/26650255/8454103 which is for your reference.

答:
Try like this;

```<code>select Output from (
select Data, c1.FullNames as LeftSideName, c2.FullNames as RightSideName, LeftSide, RightSide, REPLACE(REPLACE(Data,'[' + LeftSide + ']',c1.FullNames),'[' + RightSide + ']',c2.FullNames) as Output from (
select r.ID, Data,SUBSTRING(Data, 2, 1) LeftSide ,SUBSTRING(Data, 6, 1) RightSide from @result r ) Result
inner join @codes c1 ON Result.LeftSide = c1.ID
inner join @codes c2 ON Result.RightSide = c2.ID)
Records

Output:
10-20
10+30
40-10
</code>```

The query can perform replacing dynamically A,B,C,D,E according to @codes table etc.

Body:
Let's say I have below table script

DECLARE @result TABLE
   (
    [ID] Int
   ,[Data] Varchar(500)
   )
DECLARE @codes TABLE
   (
    [ID] Varchar(500)
   ,[FullNames] Varchar(500)
   )
INSERT   INTO @result
         SELECT   1
                 ,'[A]-[B]'
INSERT   INTO @result
         SELECT   2
                 ,'[D]-[A]'
INSERT   INTO @result
         SELECT   3
                 ,'[A]+[C]'

INSERT   INTO @codes
         SELECT   'A'
                 ,'10'
INSERT   INTO @codes
         SELECT   'B'
                 ,'20'
INSERT   INTO @codes
         SELECT   'C'
                 ,'30'
INSERT   INTO @codes
         SELECT   'D'
                 ,'40'

SELECT * FROM @result
SELECT * FROM @codes

Output of those are as below:
@result

ID  Data
--  -------
1   [A]-[B]
2   [D]-[A]
3   [A]+[C]

@codes

ID  FullNames
--  -------
A   10
B   20
C   30
D   40

Now I want output as below also:

ID  Data
--  -----
1   10-20
2   40-10
3   10+30

Please help me.
Please note: Data columns also contains ([A]-[B]+[D])*[C]

I found similar solution on https://stackoverflow.com/a/26650255/8454103 which is for your reference.

Body:
Try like this;

select Output from (
select Data, c1.FullNames as LeftSideName, c2.FullNames as RightSideName, LeftSide, RightSide, REPLACE(REPLACE(Data,'[' + LeftSide + ']',c1.FullNames),'[' + RightSide + ']',c2.FullNames) as Output from (
select r.ID, Data,SUBSTRING(Data, 2, 1) LeftSide ,SUBSTRING(Data, 6, 1) RightSide from @result r ) Result
inner join @codes c1 ON Result.LeftSide = c1.ID
inner join @codes c2 ON Result.RightSide = c2.ID)
Records

Output:
10-20
10+30
40-10

The query can perform replacing dynamically A,B,C,D,E according to @codes table etc.


问:
How to Change the Default Azure RM subscription
ASM had the ability to change the default subscription with the -Default (and now deprecated) parameter

```<code>Select-AzureSubscription -Default
</code>```

but the ARM version

```<code>Select-AzureRMSubscription
</code>```

does not have the -Default parameter.

How can I change the default ARM subscription? It is very annoying that my default is a subscription that I never use.

Edit for clarification: When I say change default subscription I mean the default subscription that you are connected to with each new PowerShell session.

答:
This is now resolved with Azure PowerShell version 5.

```<code>Enable-AzureRmContextAutosave
</code>```

Once you run this command, every new Azure PowerShell session will default to the last context set with the

```<code>Set-AzureRMContext
</code>```

command

Body:
ASM had the ability to change the default subscription with the -Default (and now deprecated) parameter

Select-AzureSubscription -Default

but the ARM version

Select-AzureRMSubscription

does not have the -Default parameter.

How can I change the default ARM subscription? It is very annoying that my default is a subscription that I never use.

Edit for clarification: When I say change default subscription I mean the default subscription that you are connected to with each new PowerShell session.

Body:
This is now resolved with Azure PowerShell version 5.

Enable-AzureRmContextAutosave

Once you run this command, every new Azure PowerShell session will default to the last context set with the

Set-AzureRMContext

command


问:
Calculation of duration from two dates during load data in datagridview
I have two columns which contains a start-date and end-date. I want to calculate the difference between those two.

I could do that after my grid has finished loading but is there any chance for doing that when I load my data to the grid?

My short code snippet from my load code

```<code>DataTable dt = new DataTable();
dt.Columns.Add("StartTime", typeof(DateTime));
dt.Columns.Add("EndTime", typeof(DateTime));
dt.Columns.Add("Duration", typeof(string));

foreach (string File in Files) {
    XDocument doc = XDocument.Load(MyXMLLocation + "\\" + File);
    XElement root = doc.Root;
    root.Descendants();

    string rootName = root.Name.LocalName;
    string logBookName = (string)root.Element("LogbookName");

    foreach (XElement timeSlot in root.Descendants("TimeSlot")) {
        DataRow newRow = dt.Rows.Add();

        newRow["StartTime"] = (DateTime)timeSlot.Elements().Where(x => x.Name.LocalName == "StartTime").FirstOrDefault();
        newRow["EndTime"] = (DateTime)timeSlot.Elements().Where(x => x.Name.LocalName == "EndTime").FirstOrDefault();
        newRow["Duration"] = "something";
</code>```

答:
```<code>DateTime start = (DateTime)timeSlot.Elements().Where(x => x.Name.LocalName == "StartTime").FirstOrDefault();
DateTime end = (DateTime)timeSlot.Elements().Where(x => x.Name.LocalName == "EndTime").FirstOrDefault();
newRow["StartTime"] = start.ToString();
newRow["EndTime"] = end.ToString();
newRow["Duration"] = (end-start).ToString();
</code>```

Body:
I have two columns which contains a start-date and end-date. I want to calculate the difference between those two.

I could do that after my grid has finished loading but is there any chance for doing that when I load my data to the grid?

My short code snippet from my load code

DataTable dt = new DataTable();
dt.Columns.Add("StartTime", typeof(DateTime));
dt.Columns.Add("EndTime", typeof(DateTime));
dt.Columns.Add("Duration", typeof(string));

foreach (string File in Files) {
    XDocument doc = XDocument.Load(MyXMLLocation + "\\" + File);
    XElement root = doc.Root;
    root.Descendants();

    string rootName = root.Name.LocalName;
    string logBookName = (string)root.Element("LogbookName");

    foreach (XElement timeSlot in root.Descendants("TimeSlot")) {
        DataRow newRow = dt.Rows.Add();

        newRow["StartTime"] = (DateTime)timeSlot.Elements().Where(x => x.Name.LocalName == "StartTime").FirstOrDefault();
        newRow["EndTime"] = (DateTime)timeSlot.Elements().Where(x => x.Name.LocalName == "EndTime").FirstOrDefault();
        newRow["Duration"] = "something";


答:
Try this:</p>

```<code>select ID, REPLACE(REPLACE(REPLACE(REPLACE(Data,
            '[A]', (select FullNames from @codes where ID = 'A')),
            '[B]', (select FullNames from @codes where ID = 'B')),
            '[C]', (select FullNames from @codes where ID = 'C')),
            '[D]', (select FullNames from @codes where ID = 'D'))
from @result
</code>```

Title: SQL Server: Replace values in field using lookup other table

Body:
Try this:

select ID, REPLACE(REPLACE(REPLACE(REPLACE(Data,
            '[A]', (select FullNames from @codes where ID = 'A')),
            '[B]', (select FullNames from @codes where ID = 'B')),
            '[C]', (select FullNames from @codes where ID = 'C')),
            '[D]', (select FullNames from @codes where ID = 'D'))
from @result


问:
Conversation - using entities values/size as a condition
I'd like to know how to use the values from the entity as a IF bot recognizes
 condition on Watson Conversation.

I have one menu for the users choose one option. And all of these options are inside one Entity called @optionsNumbers with the values: 1, 2, 3, 4, 5.

And I want to make one condition that will verify if user chooses more than one option.

E.g:

Watson: Hello, welcome to the Official Virtual Assistant from the Company XX. You can choose this options above:
1. About products 2. About Services 3. Exit

User: I want the option 1 and 2

So, the entity @sys-number have 2 values, and not just one, like I need.

As you can see, the user types 2 values of the entity @option. And I'd like to know how to recognize if the user typed more than one value for this particular entity, also @sys-number, cause the user can type just ONE option (business rules).

I'm enthusiast about Watson and pretty sure I read all documentation. So, what I have tried and does not work (I saw these methods with Intents examples):

```<code>if bot recognizes entities.sys-number[1].value
if bot recognizes entities['sys-number'].size > 1
</code>```

And I know that I can create two conditions, but if my Options menu have more than 20 options? That's why my asking.

答:
First, you could use the system number entity built-in type provided by Watson :

Entities > System Entities > Enable System Number

Your intent should now be able to recognize it easily by default, let's check the following intent :

And you test it with the sandbox, it works as expected

EDIT: Using Dialog to add a condition on sys-number

Create new dialog node for matching the intent :

Then enable the Multiple Responses for this node ( click Customize ) :

Add your conditions as part of the responses  :

Then test your dialog :

Body:
I'd like to know how to use the values from the entity as a IF bot recognizes
 condition on Watson Conversation.

I have one menu for the users choose one option. And all of these options are inside one Entity called @optionsNumbers with the values: 1, 2, 3, 4, 5.

And I want to make one condition that will verify if user chooses more than one option.

E.g:

Watson: Hello, welcome to the Official Virtual Assistant from the Company XX. You can choose this options above:
1. About products 2. About Services 3. Exit

User: I want the option 1 and 2

So, the entity @sys-number have 2 values, and not just one, like I need.

As you can see, the user types 2 values of the entity @option. And I'd like to know how to recognize if the user typed more than one value for this particular entity, also @sys-number, cause the user can type just ONE option (business rules).

I'm enthusiast about Watson and pretty sure I read all documentation. So, what I have tried and does not work (I saw these methods with Intents examples):

if bot recognizes entities.sys-number[1].value
if bot recognizes entities['sys-number'].size > 1

And I know that I can create two conditions, but if my Options menu have more than 20 options? That's why my asking.


问:
Define variables in gradle to fill data in persistence.xml
Can I define variables in gradle, which are fill in the placeholders in the persistence.xml?

Example

gradle.properties:

```<code>dev.classes= <class>my.package.class</class>.....<class>my.package.class</class>
</code>```

persistence.xml

```<code><persistence>
   <persistence-unit name "a">
     <!--define a variable that will be overwritten by build.gradle-->
       ...
  </persistence-unit>
</persistence>
</code>```

build.gradle

```<code>task replaceTokens {
  from(//persistence.xml path) {
     filter(ReplaceTokens, tokens: [//variable in xml, //value in gradle.properties])
   }
}
</code>```

I need it, because I have more persistence-units in my persistence.xml, which all needs the same classes. Currently the classes are in all persistence-unit "hardcoded". It would be nicer, if I can define it only once.

答: Sure you can, replace //value in gradle.properties by project.'dev.classes', or if your property does not contain a dot, simply dev_classes will also do.

Body:
Can I define variables in gradle, which are fill in the placeholders in the persistence.xml?

Example

gradle.properties:

dev.classes= <class>my.package.class</class>.....<class>my.package.class</class>

persistence.xml

<persistence>
   <persistence-unit name "a">

       ...
  </persistence-unit>
</persistence>

build.gradle

task replaceTokens {
  from(//persistence.xml path) {
     filter(ReplaceTokens, tokens: [//variable in xml, //value in gradle.properties])
   }
}

I need it, because I have more persistence-units in my persistence.xml, which all needs the same classes. Currently the classes are in all persistence-unit "hardcoded". It would be nicer, if I can define it only once.


问:
ASP.NET MVC2 on .NET 4.0: is [ValidateInput(false)] enough?
Good day!

I plan to upgrade my ASP.NET MVC 2 application to .NET 4.0, and have a couple of questions:

Is having [ValidateInput(false)] on action enough to accept HTML, or I need to set <httpRuntime requestValidationMode="2.0"/> as described here: ASP.NET 4 Breaking Changes

How it will work if I upgrade ASP.NET MVC to version 3 (in addition to uprading to .NET 4.0)?

Thanks in advance!

答:
You need to set <httpRuntime requestValidationMode="2.0"/> as well in ASP.NET 4.0.

The same as in ASP.NET MVC 2 (.NET 4.0) but in addition you have more fine grained control with the [AllowHtml] attribute which could be placed on a single property of your view model instead of disabling validation for the entire request:

```<code>public class MyViewModel
{
    [AllowHtml]
    public string SomeHtmlProperty { get; set; }

    public string SomeOtherProperty { get; set; }
}
</code>```

and have a controller action like this:

```<code>[HttpPost]
public ActionResult Update(MyViewModel model) { ... }
</code>```

Body:
You need to set <httpRuntime requestValidationMode="2.0"/> as well in ASP.NET 4.0.

The same as in ASP.NET MVC 2 (.NET 4.0) but in addition you have more fine grained control with the [AllowHtml] attribute which could be placed on a single property of your view model instead of disabling validation for the entire request:

public class MyViewModel
{
    [AllowHtml]
    public string SomeHtmlProperty { get; set; }

    public string SomeOtherProperty { get; set; }
}

and have a controller action like this:

[HttpPost]
public ActionResult Update(MyViewModel model) { ... }


问:
option:disabled css style does not works on Chrome and Safari for MAC
I can not change color for a disabled option on Chrome and Safari for MAC OSx. On firefox this code works. How can i override styles cross browser?

option:disabled {
  color: #a69474;
}```
<pre class="snippet-code-html lang-html prettyprint-override"><code><select>
  <option value="volvo">Volvo</option>
  <option disabled value="saab">Saab</option>
  <option value="mercedes">Mercedes</option>
  <option value="audi">Audi</option>
</select></code>```

答:
Styling of  tags is not currently supported by WebKit browsers on Mac OS X. You may find some more ideas here: Pure CSS solution to styling specific  options in webkit based browsers?.

source: CSS: Dropdown option text color not working on Mac OS X

Body:
I can not change color for a disabled option on Chrome and Safari for MAC OSx. On firefox this code works. How can i override styles cross browser?

option:disabled {
  color: #a69474;
}

<select>
  <option value="volvo">Volvo</option>
  <option disabled value="saab">Saab</option>
  <option value="mercedes">Mercedes</option>
  <option value="audi">Audi</option>
</select>


问:
filter NSArray by properties in Objective-C
I have an array of objects (Person) with type described as follow:

```<code>@inteface Person : NSObject

@property (nonatomic, strong) NSString *name;
@property (nonatomic, strong) NSNumber *age;

@end
</code>```

Is there any fast way to convert the list of Person to list of names and list of ages ?

Or better question is how to filter an array by a property of its objects?

```<code>NSArray <Person*> *list = ; //- initiate a list of people here...
NSArray <NSString*> *names;
NSArray <NSNumber*> *ages;
</code>```

答:
```<code>    NSMutableArray *personArray = [[NSMutableArray alloc] init];

    Person *p1 = [[Person alloc] init];
    p1.name = @"sam";
    p1.age = @24;
    Person *p2 = [[Person alloc] init];
    p2.name = @"sangram";
    p2.age = @25;

    [personArray addObject:p1];
    [personArray addObject:p2];

    NSArray *arrName = [personArray valueForKey:@"name"];
    NSArray *arrAge = [personArray valueForKey:@"age"];
</code>```

Body:
I have an array of objects (Person) with type described as follow:

@inteface Person : NSObject

@property (nonatomic, strong) NSString *name;
@property (nonatomic, strong) NSNumber *age;

@end

Is there any fast way to convert the list of Person to list of names and list of ages ?

Or better question is how to filter an array by a property of its objects?

NSArray <Person*> *list = ; //- initiate a list of people here...
NSArray <NSString*> *names;
NSArray <NSNumber*> *ages;


问:
Is it possible to send voice notification to Google Home device
We want to send voice notifications to Google Home device from our service when we get some specific events but not sure if it is even supported/possible.

For example, we will notify the user when the cook is almost ready like:
'Hey Ender, your meal will be ready in 5 minutes. Don't forget to take it out'

There are some scripts that claim they send voice notification to Google Home device however they seem to work in the local environment which is not our case.

One of the example scripts is posted on Reddit by @S1lentAssass1n
https://github.com/GhostBassist/GooglePyNotify

Google mentions some reminder/notification in Google Home documents but I believe it is not what we what.

https://support.google.com/googlehome/answer/7387866?co=GENIE.Platform%3DAndroid&hl=en

Any idea/help would be appreciated!

答:
Notifications on the Google Assistant platform are currently in Developer Preview. You can't release an Action that supports them, yet, and they currently on work on mobile devices - not speakers such as Google Home.

This will likely change as it moves out of Developer Preview and into production, but they haven't announced a time frame for this yet.

The solution you cite from Reddit uses the Google Home as a Chromecast Audio device, so requires a (separate) local agent to cast to it. The notes about Google Home refer to the consumer feature from Google that allows you to set notices and reminders - not for other applications.


问:
Adding Error Handlers In VB
```<code>  ' Button which allows the user to enter in there own password
    Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click

        Try
            If TextBox3.Text & TextBox6.Text & TextBox7.Text & TextBox8.Text > 0 And TextBox4.Text <> "" Then
                'input in these textboxes must be numerical
                ' It adds the passwords which is made by the user himself
                ListBox1.Items.Add("Application : " & TextBox4.Text & " Password : " & TextBox3.Text & TextBox6.Text & TextBox7.Text & TextBox8.Text & " Time : " & TimeString & " Date : " & DateTime.Today)

            End If
        Catch ex As Exception
            MessageBox.Show("Please provide correct input")

        End Try
</code>```

I'm currently making a password generator on visual basic , i have displayed the code in the part where the user can make there own password , however i wish to have some error handlers , currently i have got it working so a error message is displayed if non numeric information is entered into textbox3,6,7,8 . this works , however i wish to add two things
1. An error message if textboxes3,6,7,8 are empty
2. An error message if textbox4 is empty , curently nothing is printed in the listbox but no error message is displayed.

P.S
A beginner to vb

答:
This doesn't make sense:

```<code>If TextBox3.Text & TextBox6.Text & TextBox7.Text & TextBox8.Text > 0 And TextBox4.Text <> "" Then
</code>```

Say out loud what you want and build it up one piece at a time.  You want to display a message if TextBox3 is empty:

```<code>If TextBox3.Text = String.Empty Then
</code>```

You want to display a message if TextBox3 or TextBox6 is empty:

```<code>If TextBox3.Text = String.Empty OrElse TextBox6.Text = String.Empty Then
</code>```

Etc, etc.

Title: Adding Error Handlers In VB

Body:
  ' Button which allows the user to enter in there own password
    Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click

        Try
            If TextBox3.Text & TextBox6.Text & TextBox7.Text & TextBox8.Text > 0 And TextBox4.Text <> "" Then
                'input in these textboxes must be numerical
                ' It adds the passwords which is made by the user himself
                ListBox1.Items.Add("Application : " & TextBox4.Text & " Password : " & TextBox3.Text & TextBox6.Text & TextBox7.Text & TextBox8.Text & " Time : " & TimeString & " Date : " & DateTime.Today)

            End If
        Catch ex As Exception
            MessageBox.Show("Please provide correct input")

        End Try

I'm currently making a password generator on visual basic , i have displayed the code in the part where the user can make there own password , however i wish to have some error handlers , currently i have got it working so a error message is displayed if non numeric information is entered into textbox3,6,7,8 . this works , however i wish to add two things
1. An error message if textboxes3,6,7,8 are empty
2. An error message if textbox4 is empty , curently nothing is printed in the listbox but no error message is displayed.

P.S
A beginner to vb

Body:
This doesn't make sense:

If TextBox3.Text & TextBox6.Text & TextBox7.Text & TextBox8.Text > 0 And TextBox4.Text <> "" Then

Say out loud what you want and build it up one piece at a time.  You want to display a message if TextBox3 is empty:

If TextBox3.Text = String.Empty Then

You want to display a message if TextBox3 or TextBox6 is empty:

If TextBox3.Text = String.Empty OrElse TextBox6.Text = String.Empty Then

Etc, etc.


问:
LINQ COUNT on multiple columns
If I have a table with a title column and 3 bit columns (f1, f2, f3) that contain either 1 or NULL, how would I write the LINQ to return the title with the count of each bit column that contains 1? I'm looking for the equivalent of this SQL query:

```<code>SELECT title, COUNT(f1), COUNT(f2), COUNT(f3) FROM myTable GROUP BY title
</code>```

I'm looking for the "best" way to do it. The version I came up with dips into the table 4 times when you look at the underlying SQL, so it's too slow.

答:
If you want to stick to a LINQ query and use an anonymous type, the query could look like:

```<code> var query =
      from r in ctx.myTable
      group r by r.title into rgroup
      select new
      {
          Title = rgroup.Key,
          F1Count = rgroup.Count(rg => rg.f1 == true),
          F2Count = rgroup.Count(rg => rg.f2 == true),
          F3Count = rgroup.Count(rg => rg.f3 == true)
      };
</code>```

The trick is to recognize that you want to count the number of true fields (it gets mapped as a nullable bool), which you can do with the Count operator and a predicate. More info on the LINQ group operator here: The Standard LINQ Operators

OwnerDisplayName: gfrizzle

Title: LINQ COUNT on multiple columns

Body:
If I have a table with a title column and 3 bit columns (f1, f2, f3) that contain either 1 or NULL, how would I write the LINQ to return the title with the count of each bit column that contains 1? I'm looking for the equivalent of this SQL query:

SELECT title, COUNT(f1), COUNT(f2), COUNT(f3) FROM myTable GROUP BY title

I'm looking for the "best" way to do it. The version I came up with dips into the table 4 times when you look at the underlying SQL, so it's too slow.

LastEditorDisplayName: Fabian Steeg

Body:
If you want to stick to a LINQ query and use an anonymous type, the query could look like:

 var query =
      from r in ctx.myTable
      group r by r.title into rgroup
      select new
      {
          Title = rgroup.Key,
          F1Count = rgroup.Count(rg => rg.f1 == true),
          F2Count = rgroup.Count(rg => rg.f2 == true),
          F3Count = rgroup.Count(rg => rg.f3 == true)
      };

The trick is to recognize that you want to count the number of true fields (it gets mapped as a nullable bool), which you can do with the Count operator and a predicate. More info on the LINQ group operator here: The Standard LINQ Operators

OwnerDisplayName: OdeToCode


问:
Onclick event: divs appear one at a time
Is it possible to make based on this actual one div at a time, that is to say both of the two events onclick can't open , but if one is open and the other one is clicked the first automatically close. By the way the context which this code is used doesn't allow the use of Jquery. Thanks for your help

SOCIETES: 400

Part SBF 120 : 120

Part Filiales +100M€: 280

fermer

CONTACTS: 25 400

Part CAC 40 : 15 700

Part Filiales +100M€: 9 700

% contacts IT: 21%

fermer

EMAILS NOMINATIFS: 400

OPT OUT: 3%

LIGNES DIRECTES: 35%

```

答:
You can loop through the other elements and close them first in your "show" function</p>

```<code>function show(id) {

    var benefits = document.getElementsByClassName("benefits");
    for(var i = 0; i<benefits.length; i++){
        benefits[i].style.display="none";
    }

    if(document.getElementById('b'+id).style.display=='none') {
        document.getElementById('b'+id).style.display='block';
    }

    return false;
}
</code>```

Body:
You can loop through the other elements and close them first in your "show" function

function show(id) {

    var benefits = document.getElementsByClassName("benefits");
    for(var i = 0; i<benefits.length; i++){
        benefits[i].style.display="none";
    }

    if(document.getElementById('b'+id).style.display=='none') {
        document.getElementById('b'+id).style.display='block';
    }

    return false;
}